插槽
(1.)插槽内容
<template id="componentThree">
<p>
我是子组件模板
<slot></slot>
</p>
</template>
<div id='app'>
<component-three :title = 'doc.title'>
<h1>{{doc.title}}</h1>
</component-three>
</div>
<script>
var ComponentC = {
props:['title'],
data:function(){
return {}
},
template:"#componentThree"
}
new Vue({
el:'#app',
data:{
doc:{
title: "我是插槽的内容"
}
},
components:{
'component-three':ComponentC
}
})
</script>
- 只要在子组件模板中加入
<slot></slot>
标签,就可以在使用子组件时在其中加入任何模板代码,vue都会将其渲染出来,如果不加则无论输入什么都不会出来。 - 子组件模板中加入
<slot></slot>
标签,如下: - 子组件模板中不加
<slot></slot>
标签,如下:
总之一句话加了一切好说,不加耶稣也救不了它。
(2.)编译作用域
- 当你想在一个插槽中使用数据时,它是不能访问自组件的作用域的,比如上面的代码中插入的元素如果想使用
<component-three :title = 'doc.title'>
中的title
它是访问不到的。 - vue规则:
父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。
(3.)后备内容
- 它只在子组件中没有插入任何内容时会被渲染,例:
<template id="componentThree">
<div>
<p>happy day!!</p>
<slot>插槽后备内容</slot>
</div>
</template>
<div id='app'>
<component-three :title = 'doc.title'>
</component-three>
</div>
<script>
var ComponentC = {
props:['title'],
data:function(){
return {}
},
template:"#componentThree"
}
new Vue({
el:'#app',
data:{
doc:{
title: "我是插槽的内容"
}
},
components:{
'component-three':ComponentC
}
})
</script>
- 没有向子组件中插入任何内容:
- 如果子组件中插入一个
<h1>
标签:
(4.)具名插槽
- 有时需要实现多个插槽分块插入的需求,插入的内容有相对应的模块,对此
<slot>
标签中有name
属性,这个属性可以用来定义额外的插槽,例:
<template id="componentThree">
<div>
<p>happy day!!</p>
<slot name="head">我是头部插槽</slot>
<slot name="foot">我是尾部插槽</slot>
</div>
</template>
<div id='app'>
<component-three :title = 'doc.title'>
<h1 slot="foot">one two three!!</h1>
<h4 slot="head">we have time</h4>
</component-three>
</div>
<script>
var ComponentC = {
props:['title'],
data:function(){
return {}
},
template:"#componentThree"
}
new Vue({
el:'#app',
data:{
doc:{
age:45,
title: "我是插槽的内容"
}
},
components:{
'component-three':ComponentC
}
})
</script>
- 子组件插入的元素通过slot name的属性用
slot="name"
来匹配对应的插槽。
(5.)具名插槽v-slot
(船新版本)
- 上面使用的
slot="xx"
,在在2.6.0+ 中已弃用。 - 新版
v-slot
注意事项: - (1.) 匿名插槽在新语法下,默认指向default ,例:
v-slot:default
- (2.) 在旧版本中slot="xxx"的情况下,可以挂载在非 template标签上,如:
<h1 slot="foot">one two three!!</h1>
,新版中必须使用<template>
标签,如:<template v-slot:foot>one two three!!</template>
- (3.)
v-slot:tit
可缩写为#tit
<!--用新的v-slot替换旧的slot="xx"-->
<div id='app'>
<component-three :title = 'doc.title'>
<template v-slot:foot>one two three!!</template>
<template v-slot:head>we have time</template>
</component-three>
</div>
(6.)作用域插槽(slot-scope废弃)
- 作用:父组件访问子组件内部数据.
- (6.1) 废弃的
slot-scope
的作用域插槽:
+ 1. 语法:slot-scope="slotProps"
+ 2. 例:
<template id="componentThree">
<div>
<slot name="footer" :msg="msg"></slot>
<slot slot="headed">今天天气很不错!!!</slot>
</div>
</template>
<div id='app'>
<component-three>
<div slot='footer' slot-scope="slotProps">
{{slotProps.msg}}
</div>
<h1 name='headed'></h1>
</component-three>
</div>
<script>
var ComponentC = {
props:['title'],
data:function(){
return {
msg: 'fffffff'
}
},
template:"#componentThree"
}
new Vue({
el:'#app',
data:{
doc:{
age:45,
title: "我是插槽的内容",
msg:'hahahahah'
}
},
components:{
'component-three':ComponentC
}
})
</script>
- 在
slot
元素上任意定义一个属性,如msg
,在使用子组件时添加slot-scope
属性如slot-scope="slotProps"
(slotProps可为任意名字)接着显示,{{slotProps.msg}}
发现出现了在子组件定义的msg
的值。 - 这样插槽就可以使用父组件的值。
- 在子组件中放入父组件想让显示的内容。
- 例:
<template id="componentThree">
<div>
<ul>
<li v-for="items in personDate">
<slot name="footer" :item="items"></slot>
</li>
</ul>
</div>
</template>
<div id="app">
<component-three :person-date="personDate">
<div slot="footer" slot-scope="slotProps">
{{slotProps.item.id}}--{{slotProps.item.name}}--{{slotProps.item.sex}}
</div>
</component-three>
</div>
<script>
var componentC = {
props:["personDate"],
data:function(){
return {}
},
template:"#componentThree"
}
new Vue({
el:"#app",
data:{
personDate:[
{id:1,name:'花花',sex:'女',age:18},
{id:2,name:'小明',sex:'男',age:32},
{id:3,name:'小红',sex:'女',age:45},
{id:4,name:'小李',sex:'男',age:12},
{id:5,name:'小黄',sex:'女',age:24},
{id:6,name:'伟伟',sex:'男',age:67}
]
},
components:{
"componentThree":componentC
}
})
</script>
- 以上为完整的父子元素传递代码:主要流程
- 1. 父组件将自身数据通过props传递给子组件。
- 2. 子组件将数据传给插槽,并暴露给父组件接口,如:
:item="items"
- 3.父组件调用子组件的插槽slot接口和数据,如:
slot-scope="slotProps"
(7.)作用域插槽(船新版本)
<!--主要变化在子组件使用中-->
<div id="app">
<component-three :person-date="personDate">
<template #footer="slotProps">
{{slotProps.item.id}}--{{slotProps.item.name}}--{{slotProps.item.sex}}
</template>
</component-three>
</div>
- 其中
<div>
标签变为<template>
,#
为v-slot
简写形式。也可写为v-slot:footer="slotProps"
(7.)解构插槽prop
作用域插槽的内部工作原理是将你的插槽内容包括在一个传入单个参数的函数里
- 这意味着 v-slot 的值实际上可以是任何能够作为函数定义中的参数的 JavaScript 表达式。如:
<current-user v-slot="{ user }">
{{ user.firstName }}
</current-user>
- 它同样开启了 prop 重命名等其它可能,如:
<current-user v-slot="{ user: person }">
{{ person.firstName }}
</current-user>
- 甚至可以定义后备内容,用于插槽 prop 是 undefined 的情形:
<current-user v-slot="{ user = { firstName: 'Guest' } }">
{{ user.firstName }}
</current-user>
(8.)动态插槽名
- 动态指令参数也可以用在 v-slot 上,来定义动态的插槽名如:
<base-layout>
<template v-slot:[dynamicSlotName]>
...
</template>
</base-layout>
- 插槽详细内容:Vue 插槽
- Vue作用域插槽 :slot-scope 实例
- vue作用域插槽: vue作用域插槽,业务相关应用