美文网首页
Vue3中的slot

Vue3中的slot

作者: 飞鹰3995 | 来源:发表于2021-09-01 18:47 被阅读0次

    小编今天和大家一起探讨Vue中的插槽(slot)的概念,熟悉Vue的小伙伴都知道父子组件之间可以相互传递数据,但是传递DOM结构的时候,再通过属性的方式就有些麻烦,我们先来看个父子组件的例子。大家还可以关注我的微信公众号,蜗牛全栈。

    const app= Vue.createApp({
        template: `<myform />`
    })
    app.component('myform',{
        methods:{
            handleClick(){
                alert('handleClick')
            }
        },
        template: `<div>
            <input />
            <button @click="handleClick">提交</button>
        </div>`
    })
    const vm = app.mount("#root")
    

    上面是一个最基本的父子引用的例子,在父组件中使用的是类似h5中input单标签,有的时候我们会有这样的需求,对于上面的提交,我们有的时候希望渲染成一个按钮,有的时候我们只是希望渲染成普通div。这个时候slot就显示出威力了,我们可以把代码写成这样

    const app= Vue.createApp({
        // 将原来的单标签修改为双标签,标签之间的内容会替换掉子组件中的<slot></slot>
        template: `<myform>
                    <div>提交</div>
                  </myform>
                  <myform>
                    <button>提交</button>
                  </myform>`
    })
    app.component('myform',{
        methods:{
            handleClick(){
                alert('handleClick')
            }
        },
        // 不能在slot直接添加@click方式,可以在外面添加span标签
        template: `<div>
            <input />
            <span @click="handleClick">
                <slot></slot>
            </span>
        </div>`
    })
    const vm = app.mount("#root")
    

    其实对于slot,我们肯定不能仅仅满足于此,有的时候也需要进行数据绑定,对于父子组件,遵循的就是父组件中父组件绑定数据,子组件中子组件绑定数据。不会相互混淆

    const app= Vue.createApp({
        data(){
            return {
                f_data:'1234'
            }
        },
        template: `<myform>
                    <test />
                </myform>
                <myform>
                    {{ f_data }}
                </myform>`
    })
    app.component('myform',{
        methods:{
            handleClick(){
                alert('handleClick')
            }
        },
        template: `<div>
            <input />
            <span @click="handleClick">
                <slot></slot>
            </span>
        </div>`
    })
    
    app.component('test',{
        template: `<div>
            test component slot
        </div>`
    })
    const vm = app.mount("#root")
    

    在定义了slot之后,如果自定义组件之间什么也不传递的话,默认是空字符串,如果我们希望添加默认值的话,可以这样

    const app= Vue.createApp({
    
        template: `<myform></myform>`
    })
    app.component('myform',{
        methods:{
            handleClick(){
                alert('handleClick')
            }
        },
        template: `<div>
            <input />
            <span @click="handleClick">
                <slot>这里是插槽的默认值</slot>
            </span>
        </div>`
    })
    const vm = app.mount("#root")
    

    有时候我们希望不同的slot渲染不同的内容,这个时候,具名插槽对我们就很有用了,就像这样

    const app= Vue.createApp({
        template: `<layout>
                // 一定通过template标签,不能将v-slot作用在h5标签上
                <template v-slot:header>
                    <div>header</div>
                </template>
                <template v-slot:footer>
                    <div>footer</div>
                </template>
            </layout>`
    })
    app.component('layout',{
        template: `<div>
            <slot name="header"></slot>
            <div>content</div>
            <slot name="footer"></slot>
        </div>`
    })
    const vm = app.mount("#root")
    

    当然,我们也可以通过#简写成这样

    const app= Vue.createApp({
        template: `<layout>
                // 通过#替代v-slot
                <template #header>
                    <div>header</div>
                </template>
                <template #footer>
                    <div>footer</div>
                </template>
            </layout>`
    })
    app.component('layout',{
        template: `<div>
            <slot name="header"></slot>
            <div>content</div>
            <slot name="footer"></slot>
        </div>`
    })
    const vm = app.mount("#root")
    

    有时候,我们可能需要在子组件渲染数据,然后在父组件定义不同的标签,这个时候,我们会用到作用域标签

    const app= Vue.createApp({
        template: `
            <mylist />
            // 作用域插槽
            <mylist v-slot="slotProps">
                <span>{{slotProps.item}}</span>    
            </mylist>
            `
    })
    
    app.component('mylist',{
        data(){
            return {
                list: [1,2,3]
            }
        },
        template: `<div>
                <slot v-for="item in list" :item="item"></slot>
            </div>`
    })
    const vm = app.mount("#root")
    

    相关文章

      网友评论

          本文标题:Vue3中的slot

          本文链接:https://www.haomeiwen.com/subject/cpcfwltx.html