测试开发之前端系列!Vue 通信方式 slot (插槽)的分类

我心飞翔 分类:vue

1. Vue 中插槽的作用

在 Vue 中插槽的作用是让父组件可以向子组件指定位置插入 html 结构,也是一种组件间通信的方式,适用于:父组件向子组件传递消息。

想了解更多 Vue 组件间通信方式,可参考测试开发系列!Vue 组件间通信方式汇总,总有一款适合你( 5分钟教程-附项目实战案例 )

2. Vue 中插槽的分类

在 Vue 中插槽可分为以下三类:

  • 默认插槽
  • 具名插槽
  • 作用域插槽

3. Vue 中插槽的使用方式

1). 默认插槽

父组件内容:App.vue

<template>
   <div class="container">
       <Category title='食材'>
           <img src="https://s4.ax1x.com/2022/02/16/srJlq0.jpg" alt="">
       </Category>

       <Category title='游戏汇总'>
           <ul>
               <li v-for="(g,index) in games" :key="index">{{g}}</li>
           </ul>
       </Category>

       <Category title='电影推荐'>
           <video controls src="https://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"></video>
       </Category>
   </div>
</template>
<script>
   //引入第三方样式
   // import './assets/css/bootstrap.css'
   import Category from './components/Category'
   export default {
       name:'App',
       components: {Category},
       data(){
           return {
               foods:['鸡肉','鱼肉','牛肉','鸭肉'],
               games:['斗地主','象棋','偷菜','英雄联盟'],
               films:['《肖申克的救赎》','《霸王别姬》','《阿甘正传》','《泰坦尼克号》']
           }
       }
   }
</script>

子组件内容:Category.vue

<template>
   <div class="category">
       <h3>{{title}}分类</h3>
      <!-- 定义一个插槽(挖个坑,等着组件的调用者进行填坑) -->
       <slot>我是默认插槽的默认值,当调用者没有传递具体结构时,我就出现啦!</slot>
   </div>
</template>
<script>
   export default {
       name: "Category",
       props: ['title']
   }
</script>
2). 具名插槽

父组件内容:App.vue

<template>
   <div class="container">
       <Category title='食材'>
           <img slot="center" src="https://s3.ax1x.com/2022/02/16/srJlq0.jpg" alt="">
           <a slot="footer" href="http://www/baidu.com">更多食材</a>
       </Category>

       <Category title='游戏汇总'>
           <ul slot="center">
               <li v-for="(g,index) in games" :key="index">{{g}}</li>
           </ul>
           <div class="foot" slot="footer">
               <a href="http://www/baidu.com">单机游戏汇总</a>
               <a href="http://www/baidu.com">网络游戏汇总</a>
           </div>
       </Category>

       <Category title='电影推荐'>
           <video slot="center" controls src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"></video>
           <template  v-slot:footer>
               <div class="foot">
                   <a href="http://www/baidu.com">经典电影</a>
                   <a href="http://www/baidu.com">热门电影</a>
                   <a href="http://www/baidu.com">推荐电影</a>
               </div>
               <h4>欢迎前来观看推荐的电影</h4>
           </template>
       </Category>
   </div>
</template>
<script>
   //引入第三方样式
   // import './assets/css/bootstrap.css'
   import Category from './components/Category'
   export default {
       name:'App',
       components: {Category},
       data(){
           return {
               foods:['鸡肉','鱼肉','牛肉','鸭肉'],
               games:['斗地主','象棋','偷菜','英雄联盟'],
               films:['《肖申克的救赎》','《霸王别姬》','《阿甘正传》','《泰坦尼克号》']
           }
       }
   }
</script>

子组件内容:Category.vue

<template>
   <div class="category">
       <h3>{{title}}分类</h3>
       <!-- 定义一个插槽(挖个坑,等着组件的调用者进行填坑) -->
       <slot name="center">我是具名插槽的默认值,当调用者没有传递具体结构时,我就出现啦111</slot>
       <slot name="footer">我是具名插槽的默认值,当调用者没有传递具体结构时,我就出现啦222</slot>
   </div>
</template>
<script>
   export default {
       name: "Category",
       props: ['title']
   }
</script>
3). 作用域插槽

父组件内容:App.vue

<template>
   <div class="container">
       <Category title='游戏汇总'>
           <template scope="{games}">
               <ul>
                   <li v-for="(g,index) in games" :key="index">{{g}}</li>
               </ul>
           </template>
       </Category>

       <Category title='游戏汇总'>
           <template scope="{games}">
               <ol>
                   <li style="color:red" v-for="(g,index) in games" :key="index">{{g}}</li>
               </ol>
           </template>
       </Category>

       <Category title='游戏汇总'>
           <template slot-scope="{games}">
               <h4 v-for="(g,index) in games" :key="index">{{g}}</h4>
           </template>
       </Category>
   </div>
</template>
<script>
   //引入第三方样式
   // import './assets/css/bootstrap.css'
   import Category from './components/Category'
   export default {
       name:'App',
       components: {Category}
   }
</script>

子组件内容:Category.vue

<template>
   <div class="category">
       <h3>{{title}}分类</h3>
       <slot :games="games">我是作用域插槽的默认的一些内容!</slot>
   </div>
</template>
<script>
   export default {
       name: "Category",
       props: ['title'],
       data(){
           return {
               games:['斗地主','象棋','偷菜','英雄联盟']
           }
       }
   }
</script>

4. 总结

1.默认插槽——无插槽名称指定

默认插槽在子组件中定义插槽结构<slot>插槽默认内容...</slot>时,插槽没有定义具体名称

因此父组件在填充插槽内容时也无需指定具体是放在哪个插槽里渲染

2.具名插槽——有插槽名称指定

具名插槽在子组件中定义插槽结构<slot name="center">插槽默认内容...</slot>时,插槽给出了具体名称为:center

因此父组件在填充插槽内容时需要指定具体将内容放在哪个插槽里进行渲染,父组件指定具体插槽代码为<template slot="center">省略div内容...</template>,说明要将内容放在name = "center"的插槽里渲染

3.作用域插槽——数据存在子组件自身|数据生成结构由父组件决定

作用域插槽是数据在子组件的自身,区别于默认插槽具名插槽数据是放在父组件中的

但根据数据生成的结构需要组件的调用者(即上文示例中的父组件App.vue)来决定,这段描述对应的代码结构如下:

//App.vue文件
<template scope="{games}">
    <ol>
       <li style="color:red" v-for="(g,index) in games" :key="index">{{g}}</li>
    </ol>
</template>

回复

我来回复
  • 暂无回复内容