暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

solt插槽的理解

原创 Orange 2022-02-11
1724


内容插槽


slot 通俗的理解就是“占位”,在组件模板中占好了位置,当使用该组件标签时候,组件标签里面的内容就会自动填上这个位置(替换组件模板中 slot位置)


    const app = Vue.createApp({
        template:`
            <myform>
                <div>提交</div>
            </myform>
            <myform>
                <button>提交</button>
            </myform>
            <myform>
            </myform>
        `
    });
    app.component('myform',{
        template:`
            <input />
            <slot>默认</slot>
        `
    })

如果父组件中没有内容,即显示插槽中的内容

具名插槽


接下来如果我们有一个需求,子组件中间固定,头尾由父组件确定

    const app = Vue.createApp ({
        template :`
            <layout>
                <div>header</div>
                <div>footer</div>
            </layout>
        `
    });
    app.component('layout', {
        template :`
            <div>content</div>
            <slot></slot>
        `
    })

此时父组件中头部和尾部是连在一起的,达不到在子组件中间头尾插入的效果,此时我们就需要具名插槽为每个slot做标记


解决方法:采用多个插槽,给每个<slot>添加name


注意

1.只要出现多个插槽,始终要为所有的插槽使用完整的基于 <template>的语法

2.在 <template>中不能采用 v-slot= "header" 的写法,而是要用 v-slot: header,或者采用 v-slot的简写 #header

    const app = Vue.createApp({
        template:`
            <layout>
                <template v-slot:header>
                    <div>header</div>
                </template>
                <template v-slot:footer>
                    <div>footer</div> 
                </template>
            </layout>
        `
    });
    app.component('layout',{
        template:`
            <slot name="header"></slot>
                <div>content</div>
            <slot name="footer"></slot>
        `
    })

作用域插槽


插槽跟模板其他地方一样都可以访问相同的实例属性(也就是相同的"作用域"),要想访问到子组件作用域此时就需要使用作用域插槽


规则:父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的

需求:父组件用不同的标签循环子组件

    const app = Vue.createApp({
        template:`
            <list v-slot="slotProps">
		<div>{{slotProps.item}}</div>
	    </list>
        `
    });
    app.component('list',{
        data () {
            return {
                list: [ 1, 2, 3]
            }
        },
        template:`
            <slot v-for="item in list" :item="item"></slot>
        `
    })


代码逻辑:父组件调子组件时传递标签给 slot,子组件再通过属性的属性的方式将对应的参数传给父组件,父组件此时可采用 v-slot="slotProps"接收,即可通过 slotProps.item获得所需参数,然后再决定怎么显示


拓展:使用解构优化代码

    const app = Vue.createApp({
        template:`
            <list v-slot="{{item}}">
		<div>{{item}}</div>
	    </list>
        `
    });
    app.component('list',{
        data () {
            return {
                list: [ 1, 2, 3]
            }
        },
        template:`
            <slot v-for="item in list" :item="item"></slot>
        `
    })


用法

父组件决定子组件的渲染内容时,通过作用域插槽,可以让父组件调用子组件中的数据(访问子组件作用域)


总结


父子组件传值可使用props接收,而涉及到Dom以及标签的传值使用slot进行“占位”会简单许多,当有多个地方需要插入时,可使用多个插槽并给每个插槽一个名字,而因为插槽只能访问当前作用域,要想访问子组件作用域的数据就要使用作用域插槽调用数据。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论