ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Vue3中的slot

2021-11-01 18:32:50  阅读:170  来源: 互联网

标签:slot const app component template Vue3 组件


小编今天和大家一起探讨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")

大家还可以扫描二维码,关注我的微信公众号,蜗牛全栈

 

 

标签:slot,const,app,component,template,Vue3,组件
来源: https://www.cnblogs.com/feiying3995/p/15495302.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有