vue组件(三)之slot

本文深入探讨Vue.js中的内容分发机制与Slot的使用,包括匿名Slot、具名Slot及作用域Slot的概念与实践,通过实例解析如何在组件间灵活地插入和展示数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Slot内容分发

1、内容分发与编译作用域

在使用组件时,常常要像这样组合它们.

<app>
  <my-com></my-com>
  <my-com-2></my-com-2>
</app>

此时需要注意的是:

  1. <app> 组件不知道它的挂载点会有什么内容。挂载点的内容是由<app>的父组件决定的。
  2. <app> 组件很可能有它自己的模版。

此时很容易混乱,为了让组件可以组合,我们需要一种方式来混合父组件的内容与子组件自己的模板。这个过程被称为 内容分发

在此之前我们还需要知道编译作用域:

父组件模板的内容在父组件作用域内编译;子组件模板的内容在子组件作用域内编译。

<my-com>
  {{ message }}
</my-com>

这里的{{message}}取到的数据应该是父组件定义的数据(这里假设可以放数据),子组件my-com的数据在这里是拿不到的。

2、slot

slot是vue提供用来处理数据插槽或者说内容分发的工具。
2.1、匿名slot

以上实例中,这里的组件标签里面本来是不可以放置数据的,如果要放置数据,需要在组件的模板里面怎建一个标签,slot。

<div id="com">
    <my-com>{{message}}</my-com>
</div>

<script>
    var com_1={
        template:"<div>大家好,我是Component </div>",
        data(){
            return{
                name:"Jack"
            }
        },
        methods:{
        }
    };
    new Vue({
        el:"#com",
        data:{
          message:'Hello'
        },
        components:{
            'my-com':com_1
        }
    });

</script>

这里是无法拿到数据{{message}}的,因为没有开启插槽,我们需要在子组件的标签中怎建一个slot标签。

template:"<div>大家好,我是Component   " +
            "<slot></slot>" +
            "</div>",

这是一个匿名slot,slot的位置就是父组价中数据插入的位置。

如果默认slot中有数据,而父组件中没有数据,那么显示默认slot中的数据,否则显示父组件中插入的数据

2.2、具名slot

除了匿名slot,当然还有具名slot啦。可以给slot一个name,然后在父组件中指定slot。

在存在匿名slot的情况下,不会默认展示具名slot的数据

<div id="com">
    <my-com>
        <p>是的哦</p>
    <h2 slot="s1">有名字的插槽一</h2>
        <p>是的呢</p>
    </my-com>
</div>

<script>
    var com_1={
        template:"<div>大家好,我是Component" +
            "<slot><p>{{name}}</p></slot>"+
            "<h1><button>点击我{{name}}</button></h1>" +
                "<slot name='s1'>插槽一</slot>"+
            "</div>",

        data(){
            return{
                name:"Jack"
            }
        }
    };
    new Vue({
        el:"#com",
        components:{
            'my-com':com_1
        }
    });

</script>

在这里插入图片描述

注意:插槽的位置在哪里,数据就在那里显示
2.3、作用域插槽

这个解释比较复杂,可以说把子组件数据的作用域插到父组件中。

<div id="com">
    <my-com>
        <h2 slot="ss">数据。。。</h2>
        <template scope="itemscope">
            {{itemscope.about}}
        </template>
    </my-com>
</div>

<script>
    var com_1={
        template:"<div>{{name}}<br>" +
            "<slot :about='about'>{{name}}</slot>" +
            "<slot name='ss'></slot>" +
            "</div>",

        data() {
            return {
                name: "Jack",
                about: 'About that !!!'
            }
        }
    };
    new Vue({
        el:"#com",
        components:{
            'my-com':com_1
        }
    });

</script>

此时在父组件的template下就可以拿到子组件的数据啦。

在这里插入图片描述

3、内容分发

这就是一个内容分发的实例,在上篇组件数据传递中没有写到子链的例子,一并加入下文了。

<div id="com">
    <my-com ref="refss">Hello</my-com>
    <my-com :name="name"></my-com>
    <button @click="refs">点击</button>
</div>


<script>
    Vue.component('my-com',{
        template:'/<div><div><h2>这是一个组件</h2>' +
            '<slot><my-com-2>{{name}}</my-com-2></slot>' +
            '</div></div>/',
        data:function () {
            return{message:"global Component"}
        },
        props:['name']
        }
    );
    Vue.component('my-com-2', {
            template: '<div>我是第二个组件<slot></slot></div>'
        }
    );
    new Vue({
        el:"#com",
        data:{name:"apple"},
        methods:{
            refs(){
                //子链
                alert(this.$refs.refss.message);
                alert(this.$children[0].message)
            }
        }
    });
</script>

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值