具名插槽的由来

插槽在使用时,一个组件里有时候会同时用到多个插槽,替换的时候,不同的插槽需要替换成不同的标签,因此,每个插槽必须有一个唯一标识,name。这就是具名插槽的由来。

以标题栏为例:标题栏一般分为左、中、右三部分,每个部分都是一个slot,替换的时候根据slot的name指定具体替换哪个slot。

具名插槽的使用

 还是以标题栏为例,三个插槽分别表示左、中、右三个部分。使用的时候用户根据具体需要分别替换三个部分。替换的时候给标签设置slot属性,与slot的name对应。

复习下以前的知识点,style采用v-bind动态绑定。子组件中style写在data函数中,父组件中style以函数的形式返回style对象。

在动态绑定style的时候子组件的模板中引用的是子组件中的变量divstyle,父组件中替换slot的时候绑定style引用的是父组件vue中的方法。

这其实是因为两者的作用域不同。子组件的模板只能引用子组件中的变量和方法,父组件的模板只能引用父组件中的变量和方法。如果父组件替换插槽的时候,要引用子组件中的数据,需要设置作用域插槽。

<body>
    <div id="app">
        <mycpn>
            <img :src="backsrc" slot="left" :style="backstyle()"/>
            <input slot="middle"/>
            <label slot="right">搜索</label>
        </mycpn>
        <mycpn style="margin-top: 20px">
            <img :src="backsrc" slot="left" :style="backstyle()" />
            <label slot="middle" :style="titlestyle()">{{title}}</label>
            <img :src="messagesrc" slot="right" :style="envstyle()"/>
        </mycpn>
    </div>
    <script src="../js/vue.js"></script>
    <template id="cpn">
        <div :style="divstyle">
            <slot name="left"></slot>
            <slot name="middle"></slot>
            <slot name="right"></slot>
        </div>
    </template>
    <script>

        //相当于vue的子组件
        const mycpn={
            template:'#cpn',
            data(){
                return {
                    title: '我是子组件标题',
                    divstyle:{
                        background:'#f5f5f5',width:'250px'
                    }
                }
            },
            methods:{
            }
         }
        //创建并注册组件
        Vue.component('mycpn',mycpn);
        //vue相当于父组件
        const vue = new Vue({
            el:"#app",
            data:{
                title:"我是标题",
                backsrc:"../img/back.png",
                messagesrc:"../img/env.png"
            },
            components:{
                mycpn:mycpn
            },
            methods:{
                backstyle(){
                    return {'width':'24px','height':'24px','vertical-align':'middle'}
                },
                envstyle(){
                    return {'width':'20px','height':'20px','vertical-align':'middle'}
                },
                titlestyle(){
                    return {'display':'inline-block','width':'190px'}
                }
            }
        });
    </script>
</body>

效果如下:通过具名插槽,同一个组件可以展示不同的效果,更加灵活。

 

 

用到的两个图标:下载地址

 

Logo

前往低代码交流专区

更多推荐