Vue学习之插槽

Vue学习之插槽


一、什么是插槽?

在使用组件的时候,我们在组件的内部写了子元素,却并不会显示在页面上

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>

    <div id='app'>
        <my-com>组件内的内容</my-com>
    </div>
    <script>
        let myCom = {
            template: `
            <div>
               一个组件
            </div>
            `
        }
        Vue.component('my-com', myCom)
        new Vue({
            el: '#app',
            data: {},
            methods: {},
        })
    </script>
</body>

</html>

显示效果:
在这里插入图片描述这里并没有显示“组件内的内容”,这是因为没有使用插槽,组件不知道要把“组件内的内容”放在template中的哪个位置。

插槽相当于一个占位符,用<slot></slot> 表示,父组件可以在这个占位符中填充任何模板代码,如 HTML、组件等,填充的内容会替换子组件的标签。

二、插槽的使用

1.普通插槽

子组件

 Vue.component('my-com', {
            data() {
                return {
                }
            },

            template: `
            <div>    
                <button><slot>默认内容</slot></button>
            </div>
            `

父组件

<my-com>Hello World</my-com>

在子组件内使用<slot></slot>标签,当组件渲染的时候,<slot></slot> 将会被替换为"Hello World"。插槽内可以包含任何模板代码,甚至可以是组件。
这里从函数的角度来理解,slot为形式参数,<my-com></my-com>中的内容就为实参。Slot标签内部的内容为默认值,也就是当调用组件的时候没有设置插槽内容,则组件插槽内容默认为"默认内容"

2.具名插槽

一个组件可以有多个插槽,为了区分几个插槽,需要使用到具名插槽,具名插槽也就是给插槽取名字

子组件:

            <div>    
                <button><slot name="header"> header的内容 </slot></button>
                <button><slot name="default"> content的内容 </slot></button>
                <button><slot name="footer"> footer的内容 </slot></button>
            </div>
            

父组件:

 <my-com>

            <template v-slot:header>
                父组件header
            </template>
            
            <template v-slot:default>
                父组件content
            </template>

            <template #footer>
                父组件footer
            </template>

        </my-com>

有v-slot:插槽名,#插槽名两种传递方式

3.作用域域插槽

插槽可以传递任何文本或html元素,但仍然有局限性。比如有时会需要用把表格封装为组件,这时候需要用到作用域插槽。

具名插槽和默认插槽其实都是传递的文本,是在html标签中的内容。而作用域插槽,用的是<slot>标签上的属性的数据,这个数据可以是对象和列表。

比如,如果要用一个组件去显示一个列表
父组件:

 		<my-table :data="stus">
            <template #header>
                <th>编号</th>
                <th>姓名</th>
                <th>年龄</th>
            </template>
            <template #body="scope">
                <th>{{scope.item.id}}</th>
                <th>{{scope.item.name}}</th>
                <th>{{scope.item.age}}</th>
            </template>
        </my-table>

子组件:

 Vue.component('my-table', {
            data() {
                return {
					data: [
	                    { id: 1001, name: 'zhangsan', age: 21 },
	                    { id: 1002, name: 'lis', age: 21 },
	                    { id: 1003, name: 'wangwu', age: 21 }
                    ],
                }
            },
            template: `
                <table>
                    <thead>
                        <tr>
                            <slot name="header"></slot>
                        </tr>
                    </thead>

                    <tbody>
                        <tr v-for="(item,index) in data">
                            <slot :item="item" name="body"></slot>
                        </tr>
                     </tbody>
                </table>
            `
        })

这里在渲染的时候,是根具子组件的template为模板,<slot>标签用于占用,然后再父组件中更具插槽的名字找到相应的文本或html代码片段,填充到模板中。
父组件中 #body=scope 将子组件中v-for遍历到的对象给到了父组件,父组件根据对象的数据将内容放到<tr>中,再将这几个<tr>放到子组件模板中。
作用域插槽,实际上就实现了子组件给父组件数据。

总结

今天整理了插槽的相关知识,插槽实际上就是给模板挖几个坑,挖的坑用父组件的数据来填充。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值