【VUE】slot插槽以及作用域插槽

957 阅读2分钟

这是我参与8月更文挑战的第18天,活动详情查看:8月更文挑战

一、场景需求

<div id="app">
    <child content="<p>你好</p>"></child>
</div>
Vue.component('child', {
    props: ['content'],
    template: `<div>
                <h3>hello</h3>
                {{content}}
           </div>`
})

1.png

显然,上述效果不是我们想要的。那如何解决呢?vue官方为我们提供了<slot> 元素作为承载分发内容的出口。这样就可以实现父组件向子组件优雅地传递dom结构,子组件能够完美解析DOM。

二、slot详解

通俗易懂的讲,slot具有“占坑”的作用,在子组件占好了位置,那父组件使用该子组件标签时,新添加的DOM元素就会自动填到这个坑里面。如下:

<child>
        <p>你好</p>
</child>
Vue.component('child', {
    props: ['content'],
    template: `<div>
                <h3>hello</h3>
                <slot><slot> 
               </div>`
})

渲染后的结果就是:

1.png

注意: 如果有多个DOM元素,会一起插入到这个标签内

三、具名插槽

假设我们需要将父组件添加的HTML标签放在子组件里的不同位置。需要怎么实现呢?上面已经说了,<slot>具有占坑作用。那么当父组件的HTML标签放到子组件的不同位置时,可以给子组件占的每一个坑取名,将父组件添加的HTML元素添加到指定名字的坑,就实现了分发内容在不同位置显示。

实现方式:

  1. 先在子组件对应分发<slot>标签里,添加name='name名' 属性;

  2. 然后父组件在要分发的标签里添加 slot='name名' 属性,然后就会将对应的标签放在对应的位置了。

<div id="app">
    <child>
            <div class="header" slot="header">头部</div>
            <div class="footer"  slot="footer">底部</div>
    </child>
</div>
Vue.component('child', {
        props: ['content'],
        template: `<div>
                    <slot name='header'></slot>
                    <h3>hello</h3>
                    <slot  name='footer'><slot> 
               </div>`
})

具名插槽在父组件没有定义<slot> 时可以设置默认内容,<slot name='header'>默认内容</slot>

四、作用域插槽

作用域插槽其实就是带数据的特殊类型的插槽,用作一个 (能被传递数据的) 可重用模板,来代替已经渲染好的元素。当一个组件需要重复使用时可以用到;作用域插槽适合的场景是至少包含三级以上的组件层级,是一种优秀的组件化方案!

<div id="app">
        <child>
          <template slot-scope="childData">
                  <li>{{childData.item}}</li>
          </template>
        </child>
</div>
Vue.component('child', {
    props: ['content'],
    data: function() {
            return {
                    list: ['A', 'B', 'C']
            }
    },
    template: `<div>
                <h3>hello</h3>
                <ul>
                 // item为向上层传递的数据,单个slot在调用时转化为作用域内的多个标签
                 <slot v-for="item of list" :item="item"></slot>
                </ul>
               </div>`
})

1.png

详细解析:

  • slot-scope 相当于是一个对象,这个对象里面的数据就是子组件插槽绑定传上来的;

  • <template> 方式是固定的模版,必写;

  • 子组件中的item 为向上层传递的数据,单个slot在调用时转化为作用域内的多个标签。

~~别走,点个赞吧~~~~