Ashun's 技術駅 Ashun's 技術駅
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • HTML
  • CSS
  • Vue
  • 现代web布局
  • React
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 技术资源
  • 第一阶段

    • HTML
  • 第二阶段

    • JavaScript
  • 第三阶段

    • Vue
  • 第四阶段

    • 实战项目
  • 每周测试

    • 每周
  • 其他

    • Vue引入UI框架
    • Web前端面试
    • Vue3-resource
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 福利资源
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Ashun

前端界的小学生
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • HTML
  • CSS
  • Vue
  • 现代web布局
  • React
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 技术资源
  • 第一阶段

    • HTML
  • 第二阶段

    • JavaScript
  • 第三阶段

    • Vue
  • 第四阶段

    • 实战项目
  • 每周测试

    • 每周
  • 其他

    • Vue引入UI框架
    • Web前端面试
    • Vue3-resource
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 福利资源
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • HTML

  • CSS

  • Vue

    • 01Vue中v-slot插槽详解
      • 不使用插槽
      • 默认插槽
      • 具名插槽
      • 作用域插槽
      • 动态插槽名
      • 和具名插槽的缩写
      • 完整代码
  • 现代web布局

  • React

  • 页面
  • Vue
xugaoyi
2022-04-18
目录

01Vue中v-slot插槽详解

# Vue中v-slot插槽详解

参考博文:https://blog.csdn.net/weixin_45755816/article/details/120500714 (opens new window)

  • 准备工作
    • 搭建vite (opens new window)
    • 安装Windi CSS (opens new window) 或者 Tailwind (opens new window)
    • 安装教程https://ashun.gq/#/pages/6e9d46/ (opens new window)

# 不使用插槽

<!--App.vue 父组件-->
<template>
 <div class="container flex flex-row justify-center">
   <!--将title和listData数据传给子组件,下面展示了两种使用组件方式-->
   <Category title="动漫" :listData="cartoons"></Category>
   <Category title="游戏" :listData="games"/>
   <Category title="电影" :listData="films"/>
 </div>
</template>

<script>
import Category from './components/category.vue'
export default {
  name: 'App',
  components: {
    Category
  },
  data(){
    return{
      cartoons:['海贼王','名侦探柯南','一人之下','未闻花名'],
      games:['4399','斗地主','王者荣耀','和平精英'],
      films:['《你好,李焕英》','《夏洛特烦扰》','《你的名字》','《蜘蛛侠》']
    }
  }
}
</script>

<style scoped>
.footer a {
  @apply ml-10;
}
.container {
  background-image: url(https://cdn.jsdelivr.net/gh/ashunun/netbian/bian/1.jpg);
  @apply h-200 bg-auto bg-cover bg-contain;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<!-- category 组件子-->
<template>
 <div>
     <h3>{{ title }}分类</h3>
      <ul>
        <li v-for="(item,index) in listData" :key="index">{{item}}</li>
      </ul>
 </div>
</template>

<script>
export default {
  name:'Category',
  //props接收传过来的数据
  props:['listData','title']
}
</script>

<style scoped>
div{
  @apply bg-yellow-200 m-5 w-60 h-100 rounded-lg shadow-lg shadow-yellow-700/50;
}
h3{
  @apply text-center bg-yellow-600 text-xl;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 默认插槽

<!--App.vue 父组件-->
<template>
 <div class="container flex flex-row justify-center">
   <!--将title和listData数据传给子组件,下面展示了两种使用组件方式-->
   <Category title="动漫" :listData="cartoons">
     <img class="w-60" src="https://img2.baidu.com/it/u=4117582627,679171248&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500" alt="">
   </Category>
   <Category title="游戏" >
      <ul>
        <li v-for="(g,index) in games" :key="index">{{g}}</li>
      </ul>
   </Category>
   <Category title="电影">
     <video class="w-60" controls src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"></video>
   </Category>
 </div>
</template>

<script>
import Category from './components/category.vue'
export default {
  name: 'App',
  components: {
    Category
  },
  data(){
    return{
      cartoons:['海贼王','名侦探柯南','一人之下','未闻花名'],
      games:['4399','斗地主','王者荣耀','和平精英'],
      films:['《你好,李焕英》','《夏洛特烦扰》','《你的名字》','《蜘蛛侠》']
    }
  }
}
</script>

<style scoped>
.footer a {
  @apply ml-10;
}
.container {
  background-image: url(https://cdn.jsdelivr.net/gh/ashunun/netbian/bian/1.jpg);
  @apply h-200 bg-auto bg-cover bg-contain;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<!-- category 组件子-->
<template>
 <div>
    <h3>{{ title }}分类</h3>
    <!-- 定义一个插槽,等着组件的使用者(<Category>填充内容</Category>)进行填充 -->
    <slot>这里可以填写默认值,当组件使用者没有进行填充时,会显示</slot>      
 </div>
</template>

<script>
export default {
  name:'Category',
  //props接收传过来的数据
  props:['listData','title']
}
</script>

<style scoped>
div{
  @apply bg-yellow-200 m-5 w-60 h-100 rounded-lg shadow-lg shadow-yellow-700/50;
}
h3{
  @apply text-center bg-yellow-600 text-xl;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# 具名插槽

<!--App.vue 父组件-->
<template>
 <div class="container flex flex-row justify-center">
    <!--将title和listData数据传给子组件,下面展示了两种使用组件方式-->
    <Category title="动漫" :listData="cartoons">
    <!--使用具名插槽,需要用template标签包裹着,并使用v-slot:name -->
     <template v-slot:center>
        <img class="w-60" src="https://img2.baidu.com/it/u=4117582627,679171248&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500" alt="">
     </template>
     <template v-slot:foot>
      <a  href="https://image.baidu.com/search/index?tn=baiduimage&ct=201326592&lm=-1&cl=2&ie=gb18030&word=%B6%AF%C2%FE%CD%BC%C6%AC&fr=ala&ala=1&alatpl=normal&pos=0">更多照片</a>
     </template>  
   </Category>
    <Category title="游戏" >
      <template v-slot:center>
          <ul>
            <li v-for="(g,index) in games" :key="index">{{g}}</li>
          </ul>
      </template>
       <template v-slot:foot>
          <div  class="footer">
            <a href="https://www.csdn.net/">手机游戏</a>
            <a href="https://www.csdn.net/">电脑游戏</a>
          </div>
      </template>
    </Category>
   <Category title="电影">
     <template v-slot:center>
      <video class="w-60" controls src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"></video>
     </template>
      <template v-slot:foot>
        <div class="footer">
            <a href="https://www.csdn.net/">经典</a>
            <a href="https://www.csdn.net/">热门</a>
            <a href="https://www.csdn.net/">推荐</a>
       </div>
      </template>
   </Category>
 </div>
</template>

<script>
import Category from './components/category.vue'
export default {
  name: 'App',
  components: {
    Category
  },
  data(){
    return{
      //cartoons:['海贼王','名侦探柯南','一人之下','未闻花名'],
      games:['4399','斗地主','王者荣耀','和平精英'],
      //films:['《你好,李焕英》','《夏洛特烦扰》','《你的名字》','《蜘蛛侠》']
    }
  }
}
</script>

<style scoped>
.footer a {
  @apply ml-10;
}
.container {
  background-image: url(https://cdn.jsdelivr.net/gh/ashunun/netbian/bian/1.jpg);
  @apply h-200 bg-auto bg-cover bg-contain;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<!-- category 组件子-->
<template>
 <div>
    <h3>{{ title }}分类</h3>
    <!-- 定义一个插槽,等着组件的使用者(<Category>填充内容</Category>)进行填充 -->
    <slot name="center">这里可以填写默认值,当组件使用者没有进行填充时,center会显示</slot>
    <slot name="foot">这里可以填写默认值,当组件使用者没有进行填充时,foot会显示</slot>    
 </div>
</template>

<script>
export default {
  name:'Category',
  //props接收传过来的数据
  props:['listData','title']
}
</script>

<style scoped>
div{
  @apply bg-yellow-200 m-5 w-60 h-100 rounded-lg shadow-lg shadow-yellow-700/50;
}
h3{
  @apply text-center bg-yellow-600 text-xl;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 作用域插槽

<!--App.vue 父组件-->
<template>
 <div class="container flex flex-row justify-center">
  <!--将title和listData数据传给子组件,下面展示了两种使用组件方式-->
    <Category title="动漫" :listData="cartoons">
      <!--使用具名插槽,需要用template标签包裹着,并使用v-slot:name -->
      <template v-slot:default="obj">
        <ul>
          <li v-for="(g, index) in obj.cartoons" :key="index">{{ g }}</li>
        </ul>
      </template>
    </Category>
    <Category title="游戏">
      <!-- 默认插槽的 slot 简便写法 -->
      <template v-slot="obj">
        <ol>
          <li v-for="(g, index) in obj.games" :key="index">{{ g }}</li>
        </ol>
        <ul>
          <li v-for="(g, index) in obj.msg" :key="index">🐱‍🐉插槽{{ g }}</li>
        </ul>
      </template>
    </Category>
    <Category title="电影">
      <!-- 解构插槽 -->
      <template v-slot="{ films, msg }">
        <div>
          <h4 v-for="(g, index) in films" :key="index">{{ g }}</h4>
          <h3 v-for="(g, index) in msg" :key="index">🐱‍🐉插槽{{ g }}</h3>
        </div>
      </template>
    </Category>
 </div>
</template>

<script>
import Category from './components/category.vue'
export default {
  name: 'App',
  components: {
    Category
  },
  data(){
    return{
      //cartoons:['海贼王','名侦探柯南','一人之下','未闻花名'],
      //games:['4399','斗地主','王者荣耀','和平精英'],
      //films:['《你好,李焕英》','《夏洛特烦扰》','《你的名字》','《蜘蛛侠》']
    }
  }
}
</script>

<style scoped>
.footer a {
  @apply ml-10;
}
.container {
  background-image: url(https://cdn.jsdelivr.net/gh/ashunun/netbian/bian/1.jpg);
  @apply h-200 bg-auto bg-cover bg-contain;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<!-- category 组件子-->
<template>
 <div>
    <h3>{{ title }}分类</h3>
    <!-- 定义一个插槽,等着组件的使用者(<Category>填充内容</Category>)进行填充 -->
    <slot :cartoons="cartoons">默认插槽</slot>
    <slot :games="games">默认插槽</slot>
    <slot :films="films">默认插槽</slot>
    <slot :msg="msg"></slot>  
 </div>
</template>

<script>
export default {
  name:'Category',
  //props接收传过来的数据
  props: ["listData", "title"],
  data(){
    return{
      cartoons: ["海贼王", "名侦探柯南", "一人之下", "未闻花名"],
      games: ["4399", "斗地主", "王者荣耀", "和平精英"],
      films: [
        "《你好,李焕英》",
        "《夏洛特烦扰》",
        "《你的名字》",
        "《蜘蛛侠》",
      ],
      msg: [",👀作用域", "芭比"],
    }
  }
}
</script>

<style scoped>
div{
  @apply bg-yellow-200 m-5 w-60 h-100 rounded-lg shadow-lg shadow-yellow-700/50;
}
h3{
  @apply text-center bg-yellow-600 text-xl;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

# 动态插槽名

<!--App.vue 父组件-->
<template>
  <div class="container flex flex-col justify-center items-center">
    <Category title="游戏">
      <!-- v-slot: 缩写法 # -->
      <template #[dynamicSlotName]="obj">
        <ol>
          <li v-for="(g, index) in obj.games" :key="index">{{ g }}</li>
        </ol>
      </template>
    </Category>
    <button @click="change">点这切换</button>
  </div>
</template>

<script>
import Category from "./components/category.vue";

export default {
  name: "App",
  components: {
    Category,
  },
  data() {
    return {
      dynamicSlotName: "1",
    };
  },
  methods: {
    change() {
      if (this.dynamicSlotName == "1") {
        this.dynamicSlotName = "2";
      } else this.dynamicSlotName = "1";
    },
  },
};
</script>

<style scoped>
.footer a {
  @apply ml-10;
}
.container {
  background-image: url(https://cdn.jsdelivr.net/gh/ashunun/netbian/bian/1.jpg);
  @apply h-200 bg-auto bg-cover bg-contain;
}
button {
  @apply rounded-lg p-2 w-30 cursor-pointer bg-gradient-to-r from-violet-500 to-fuchsia-500 hover:from-violet-700 text-white shadow-lg shadow-indigo-700/80 text-center;
  border: none;
}
</style>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<!-- category 组件子-->
<template>
 <div>
    <h3>{{ title }}分类</h3>
 <!-- 具名+作用域 插槽 -->
    <!--两个插槽,传递的数据不一样。-->
    <slot name="1" :games="games1"></slot>
    <slot name="2" :games="games2"></slot> 
 </div>
</template>

<script>
export default {
  name:'Category',
  //props接收传过来的数据
  props: ["listData", "title"],
  data(){
    return{
      games1:['4399','斗地主','王者荣耀','和平精英'],
      games2:['我的世界','cf','LOL','cs']
    }
  }
}
</script>

<style scoped>
div{
  @apply bg-yellow-200 m-5 w-60 h-100 rounded-lg shadow-lg shadow-yellow-700/50;
}
h3{
  @apply text-center bg-yellow-600 text-xl;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# 和具名插槽的缩写

跟 v-on 和 v-bind 一样,v-slot 也有缩写,即把参数之前的所有内容 (v-slot:) 替换为字符 #

<template #center>
</template>
1
2

# 完整代码

代码 (opens new window)

推荐一个加速软件——DivSidecar (opens new window) 意为为开发者打辅助的边车工具,通过本地代理的方式将https请求代理到一些国内的加速通道上 1、GitHub打不开,加速Github 很有用。 2、dns优选(解决污染问题) 3、Stack Overflow 加速 4、npm加速

编辑 (opens new window)
上次更新: 2023/08/06, 00:38:41
CSS给table的tbody添加滚动条
01Web 布局技术演进:了解 Web 布局发展史

← CSS给table的tbody添加滚动条 01Web 布局技术演进:了解 Web 布局发展史→

最近更新
01
课件-react路由-V6
01-22
02
课件-国际化
01-22
03
课件-redux-toolkit
01-22
更多文章>
Theme by Vdoing | Copyright © 2019-2024 Evan Xu | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式