一篇文章彻底理解学会Vue插槽

所谓组件的插槽,简单来说就是在子组件中预留一定的位置,父组件可以向该位置传递内容。

基本插槽

子组件预留的位置:

<slot>默认内容</slot>

父组件向子组件分发内容

<!-- 组件包着的内容就是向子组件分发的内容 -->
<组件名称>要分发的内容</组件名称>
基本例子
    <div id="test">
     <!-- 使用组件 -->
     <!-- 如果使用子组件的时候没有传递数据,则使用子组件插槽的默认内容 -->
        <btn></btn>
        <!-- 如果使用子组件的时候传递有数据,则使用父组件传递的内容 -->
        <btn>这是我的按钮</btn>
    </div>
    <script src="./vue.js"></script>
    <script>
        Vue.component('btn', {
            // 通过<slot></slot>预留插槽
            template: `<button><slot>按我</slot></button>`
        })
        new Vue({
            el: '#test'
        })
    </script>
具名插槽

所谓具名插槽,就是指有名字的插槽,就是子组件在预留插槽位置的时候,可以设置插槽的名字,父组件在向子组件分发内容的时候,可以根据名字向不同的插槽分别分发内容

    <div id="test">
       <xxx>你好吗</xxx>
       <div>****************</div>
       <xxx>
           <span slot="boy">学习Java从入门到放弃</span>
           <span slot="girl">数据库从删库到跑路/span>
           <span slot="boy">学习Vue从入门到大神</span>
           66666
       </xxx>
    </div>
    <script src="./vue.js"></script>
    <script>
        Vue.component('xxx', {
            // 通过<slot></slot>预留插槽
            template: `<div>
                        <div style="color: green;">
                            <slot name="boy"></slot>
                        </div>
                        <div style="color: pink;">
                            <slot name="girl"></slot>
                        </div>
                        <div style="color: blue;">
                            <slot></slot>
                        </div>
                    </div>`
        })
        new Vue({
            el: '#test'
        })
    </script>

从上面的例子我们可以看出,组件在预留插槽的时候是这样的:

		<div>
        <div style="color: green;">
            <!-- 名字为boy的插槽 -->
            <slot name="boy"></slot>
        </div>
        <div style="color: pink;">
            <!-- 名字为girl的插槽 -->
            <slot name="girl"></slot>
        </div>
        <div style="color: blue;">
            <!-- 没名字的插槽 -->
            <slot></slot>
        </div>
    </div>

父组件向子组件分发内容是这样的:

		<div id="test">
        <xxx>你好啊</xxx>
        <div>****************</div>
        <xxx>
            <span slot="boy">吃饭</span>
            <span slot="girl">睡觉</span>
          	<span slot="boy">打豆豆</span>
            666
        </xxx>
    </div>

分发规则就是:父组件分发内容时,是按照名字分发到对应的插槽中,如果分发的内容没有名字,就是分发到无名字的子组件插槽。

使用template标签进行批量具名分发

对于一次性需要分发的内容比较多的时候,可以使用一个叫template的标签,一块分发。

    <div id="test">
        <xxx>
            <!-- 对于多个,我们可以使用一个固定的template标签进行分发 -->
            <template slot="boy">
                <span>吃饭</span>
                <span>睡觉</span>
            </template>
            <span slot="girl">打豆豆</span>
            666
        </xxx>
    </div>
作用域插槽

作用域插槽一般用在子组件的内容需要在父组件中处理的时候

    <div id="test">
        <xxx>
            <!-- sonData是子组件绑定的数据,名字可以自己定 -->
            <template slot-scope="sonData">
               <span v-if="sonData.king.camp == '蜀国大帝'" style="color: red;">{{sonData.king.name}}  --- {{sonData.king.camp}}</span>
               <span v-else>{{sonData.king.name}}  --- {{sonData.king.camp}}</span>
            </template>
        </xxx>
    </div>
    <script src="./vue.js"></script>
    <script>
        Vue.component('xxx', {
            data() {
                return {
                    kings: [
                        {name: '曹操', camp: '魏国大帝'},
                        {name: '孙权', camp: '吴国大帝'},
                        {name: '刘备', camp: '蜀国大帝'},
                    ]
                }
            },
            template: `<ul>
                            <!-- 子组件定义插槽的同时,绑定一个属性(名字自定),绑定的数据可以被父组件捕获到 -->
                            <li v-for="i in kings"><slot :king="i">{{i.name}}</slot></li>
                        </ul>`
        })
        new Vue({
            el: '#test'
        })
    </script>

从例子中我们可以看出,在子组件中定义插槽的时候,可以绑定一个属性(名字自定),该属性绑定的数据可以被父组件捕获到。

template: `<ul><li v-for="i in kings"><slot :king="i">{{i.name}}</slot></li></ul>`

在父组件中,可以通过 slot-scope 属性捕获到子组件绑定的数据,然后我们就可以自由的修改数据,修改后的数据会再次分发到子组件中

<xxx>
  <!-- sonData是子组件绑定的数据,名字可以自己定 -->
  <template slot-scope="sonData">
    <!--这里的king就是子组件绑定的属性名,这个要一致-->
    <span v-if="sonData.king.camp =='蜀国大帝'" style="color:red;">{{sonData.king.name}}</span>
    <span v-else>{{sonData.king.name}}</span>
  </template>
</xxx>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值