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
原文地址:https://www.cnblogs.com/OrochiZ-/p/11784847.html