Vue.js slot插槽

Posted ---空白---

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue.js slot插槽相关的知识,希望对你有一定的参考价值。

1.个人理解的插槽

之所以使用组件,就是因为组件可以将复杂的页面分割成多个部分,每个 部分就是一个组件(也是一个vue文件)。要使用这个组件,只需要引入组件文件,并在模版中写入组件标签即可,引入了这个子组件,就相当于引入了这个组件的html模版,例如:

// App.vue
<template>
    <div id="app">
        <Child />
    </div>
</template>
// Child组件
<template>
    <div id="child">
        <h2>我是Child组件</h2>
    </div>
</template>

渲染之后就是

<div id="app">
   <div id="child">
      <h2>我是Child组件</h2>
   </div>
</div>

父组件想要插入数据到子组件中,无非就是将数据通过属性绑定的形式,然后子组件通过props接收。但是这种方法只能用来传递一些纯数据(对象和数组),无法传入一段html代码给子组件,slot就是为此而生的

2.slot基本用法

在原生的html中,我们经常在一个块级标签中插入n个标签,Vue中父组件给子组件插入标签也是这种写法

// App.vue
<template>
  <div id="app">
    <Child>
      <!-- 在子组件中插入标签 -->
      <h2>我是插入的h2</h2>
    </Child>
  </div>
</template>

父组件给子组件插入(传递)一段html标签,子组件需要一个位置进行接收,这个位置就是子组件的slot标签。slot标签的位置就是插入标签的位置

// 子组件
<template>
    <div id="child">
<!-- slot标签将被插入的标签替代 -->
        <slot></slot>
        <h2>我是Hello组件</h2>
    </div>
</template>

渲染结果:

<div id="app">
    <div id="child">
        <h2>我是插入的h2</h2>
        <h2>我是Child组件</h2> 
    </div>
</div>

这种插槽一个,被称为匿名插槽。

3具名插槽

如果子组件有多个插槽,就需要为每个插槽添加一个标识,即name属性,方便对号入座

<template>
    <div id="child">
        <slot name="top"></slot>
        <h2>我是Child组件</h2>
        <slot name="bottom"></slot>
    </div>
</template>

父组件插入标签时 通过设定slot属性,对比slot的name属性值,来关联对应的插槽

<template>
  <div id="app">
    <Child>
      <!-- 在子组件中插入标签 -->
      <h2 slot="top">我是插入的h2</h2>
      <h5 slot="bottom">我是插入的h5</h5>
    </Child>
  </div>
</template>

渲染结果:

<div id="app">
    <div id="child">
        <h2>我是插入的h2</h2>
        <h2>我是Child组件</h2> 
        <h5>我是插入的h5</h5>
    </div>
</div>

PS:插槽可以空着不用,父组件不插入标签元素,插槽就不会被渲染,利用这个特性可以控制子组件的某些空间是否展示对应的元素
插槽和props传参可以同时使用,两者不冲突

4.插槽的默认内容

slot标签内可以写html代码,如果这个插槽没有被替换,会显示该插槽内的html内容,反之会被替换

<template>
    <div id="child">
        <slot name="top">
          <p>我是top插槽没使用的时候展示的内容</p>
        </slot>
        <h2>我是Child组件</h2>
        <slot name="bottom"></slot>
    </div>
</template>
// App.vue
<template>
  <div id="app">
    <Child>
      <h5 slot="bottom">我是插入的h5</h5>
    </Child>
  </div>
</template>

渲染结果:name="top"的插槽显示默认的内容

<div id="app">
    <div id="child">
        <p>我是top插槽没使用的时候展示的内容</p> 
        <h2>我是Child组件</h2>
        <h5>我是插入的h5</h5>
    </div>
</div>

5.slot-scope(作用域插槽) 为slot标签绑定数据

这个功能类似反向props,子组件通过属性绑定的形式,将相应的数据绑定到slot标签中,当父组件要插入标签来替换这个slot时,就可以读取这个绑定在slot标签中的数据

// 子组件
<template>
    <div id="child">
 <!-- 在slot标签中2个数据 -->
        <slot name="top" :p1="p1" :p2="p2">
        </slot>
        <h2>我是Hello组件</h2>
        <slot name="bottom"></slot>
    </div>
</template>

<script>
export default {
  data () {
    return {
      p1: {name: '乔治',age: 4},
      p2 :{name: '佩琪',age: 8}
    }
  }
}
</script>

父组件在替代slot的标签中添加 slot-scope属性,表示接受当前slot绑定的数据。slot-scope的值可以随意写,例如slot-scope="xxx"
因为slot标签上可能绑定了多个数据,所以vue将所有的数据都包裹在一个对象内,可以通过这个对象的属性名来访问对应的数据。

// App.vue
<template>
  <div id="app">
    <Hello>
      <template slot-scope="xxx" slot="top">
        <p>{{xxx.p1.name}}</p>
        <p>{{xxx.p1.age}}岁</p>
        <p>{{xxx.p2.name}}</p>
        <p>{{xxx.p2.age}}岁</p>
      </template>
      <h5 slot="bottom">我是插入的h5</h5>
    </Hello>
  </div>
</template>

xxx.p1.name => 乔治
xxx.p1.age => 4
xxx.p2.name => 佩琪
xxx.p2.age => 8

以上是关于Vue.js slot插槽的主要内容,如果未能解决你的问题,请参考以下文章

Vue.js slot插槽

Vue.js(17)之 插槽

将插槽传递到 Vue.js 中的插槽

Vue.js 3 - 将组件插入插槽

Vue.js 源码分析—— Slots 是如何实现的

vue.js的插槽 - slot 是啥?要我说,它就是个“形参”