VUE组件:slot(插槽)

作用

Slot是为了更好的实现组件的组合而出现,特别是父子组件的内容

slot用法

①一般而言,组件标签间的内容会被抛弃

正常情况下,我们在自定义组件标签中定义的任何内容,都会被抛弃。都只会渲染出组件模板内容,如下:

在这里插入图片描述


②Slot可以把内容渲染进子组件

我们使用slot就能实现让我们的内容渲染进行子组件中,达到如同使用网页标签一样使用我们的组件标签
在这里插入图片描述


③组件标签中放入其他组件也能渲染进去

在这里插入图片描述


④slot中可以给默认值

在这里插入图片描述


⑤Slot给我们带来的好处

  1. 让我们如同使用网页标签一样使用组件标签
  2. 当我们要让组件组合使用,比如混合父组件的内容与子组件的模板时,特别有用

⑥具名slot (具有名字的插槽)——重点

在这里插入图片描述
在这里插入图片描述
完整代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <script src="./node_modules/_vue@2.6.10@vue/dist/vue.js"></script>
    <title>slot插槽</title>
</head>

<body>
    <div id="app">
        <body-component></body-component>
        <body-component>
            <footer-component slot="footer"></footer-component>
            <header-component slot="header"></header-component>
            <main-component></main-component>
        </body-component>
    </div>
    <script>
        Vue.component('body-component', {
            template: `
            <div>
                我是父组件
                <slot name='header'></slot> <!-- 这里放入头部 -->
                <slot></slot> <!-- 这里放入内容 -->
                <slot name='footer'></slot> <!-- 这里放入尾部 -->
            </div>`,
        });
        Vue.component('header-component', {
            template: `
            <div>我是头部</div>`,
        });
        Vue.component('main-component', {
            template: `
            <div>我是内容</div>`,
        });
        Vue.component('footer-component', {
            template: `
            <div>我是尾部</div>`,
        });
        var vueApp = new Vue({
            el: '#app',
        })
    </script>
</body>
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190414175117402.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MTM1MDIyNQ==,size_16,color_FFFFFF,t_70)
</html>

从上可知:

  1. 然后具名slot可以和没有名字的默认slot 共存,父组件中没有绑定具名slot的元素都将出现在子组件的默认slot中。【如果有多个无名的slot,那就会渲染插入多次】
  2. 如果父组件中含有没有绑定具名slot的元素,但是子组件中却无匿名默认slot时,父组件的那些原生将会被抛弃

⑦作用域插槽

在这里插入图片描述
在这里插入图片描述

作用域插槽的用法特点

  1. 在子组件中写slot插槽时,给上属性(这些属性能够被父组件拿到)
  2. 在父组件中渲染内容时一般写template标签,并且标签上有个scope属性,这个属性的值为一个对象,就是子组件的slot插槽上所有属性的集合
  3. 在父组件中就可以通过scope属性值这个对象操作子组件提供的数据

作用域插槽也是可以具名的,即为一个拥有名字的slot
在这里插入图片描述
之后上源码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <script src="./node_modules/_vue@2.6.10@vue/dist/vue.js"></script>
    <title>Document</title>
</head>
<body>
    <div id="app">
        <todo-list>
            <template scope="slotVal" slot="li">
                <span v-if='slotVal.val%2==0'>能被2整除</span>
                <span v-else>不能</span>
                {{slotVal.val}}
            </template>
        </todo-list>
    </div>
    <script>
        Vue.component('todo-list',{
            template:`
            <ul>
                <li v-for='v in list'>
                <slot name='li' :val='v'>{{v}}</slot>
                </li>
            </ul>
            `,
            data:function() {
                return {
                    list:[1,2,3,4,5]    
                }
            },
        })
        var vueApp = new Vue({
            el:'#app'
        })
    </script>
</body>
</html>

⑧访问slot插槽

在这里插入图片描述
效果图
在这里插入图片描述
注意: 空文本元素也会作为获取的slot数组中的一个元素

源码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <script src="./node_modules/_vue@2.6.10@vue/dist/vue.js"></script>
    <title>slot插槽</title>
</head>

<body>
    <div id="app">
        <body-component>
            <footer-component slot="footer"></footer-component>
            <header-component slot="header"></header-component>
            <main-component></main-component>
        </body-component>
    </div>
    <script>
        Vue.component('body-component', {
            template: `
            <div>
                <button @click='gelAllSlot'>获取所有的插槽</button>
                <slot name='header'></slot> <!-- 这里放入头部 -->
                <slot></slot> <!-- 这里放入内容 -->
                <slot name='footer'></slot> <!-- 这里放入尾部 -->
            </div>`,
            methods: {
                gelAllSlot:function(){
                    var header = this.$slots.header;
                    var main = this.$slots.default;
                    var footer = this.$slots.footer;
                    console.log(header,main,footer);//每个插槽打印出来都是一个数组
                    console.log(header[0].elm)
                }
            },
        });
        Vue.component('header-component', {
            template: `
            <div>我是头部</div>`,
        });
        Vue.component('main-component', {
            template: `
            <div>我是内容</div>`,
        });
        Vue.component('footer-component', {
            template: `
            <div>我是尾部</div>`,
        });
        var vueApp = new Vue({
            el: '#app',
        })
    </script>
</body>

</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值