[vue]之插槽slot
最开始听到插槽,实在是有点迷惑,在深入学习之后,我自己把它用【占位】来理解,其实官网已经说的很清楚了,为啥还要写一遍呢,我感觉自己梳理一遍写出来,会让自己更加深入的理解概念和用法。
以下都是基于官网最新,不包含废弃的。
一:插槽内容
简单的理解就是:
1:在父组件中的子组件里边加入自己想要的内容,然后跟子组件里边的内容混在一起;
2:如果父组件中的子组件有内容,就展示该内容,子组件中的slot则被忽略;
3:如果父组件中的子组件没有内容,就展示子组件里边slot占位里边的内容。
好像还是不太明白,是吗?哭笑的表情,还是代码实在。
父组件:
<template>
<div>
<h1>solt</h1>
<Children>
</Children>
</div>
</template>
子组件(Children):
<template>
<div>
<slot>我是占位内容,如果子组件(Children)里边有值我就不显示,反之,我就显示。</slot>
<h2>我是子组件内容</h2>
</div>
</template>
二:编译作用域
刚接触这个概念的时候,还是有点蒙的,理解之后再去看文档,很有道理,哈哈。其实就是插槽模板可以访问父组件的值,但是不可以访问子组件内部的值。
看下边的代码,其实就是父组件内的Children下的插槽可以访问父组件的数据msg,但是访问不了Children组件内的names,这就是插槽的作用域。
作为一条规则,请记住:
父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。
父组件:
<template>
<div>
<h1>solt</h1>
<Children>
{{ msg }}
</Children>
</div>
</template>
<script>
const Children = () => import('@/pages/solt/children');
export default {
data(){
return {
msg:"我是内容"
}
},
components: {
Children
}
}
</script>
子组件:
<script>
export default {
data () {
return {
names:"abc"
}
},
props:['url']
}
</script>
三:后备内容
其实就是最开始的这一句解释:
3:如果父组件中的子组件没有内容,就展示子组件里边slot占位里边的内容
四:具名插槽
简单的字面理解就是:具有名字的插槽。
看代码一目了然,这里有一个注意点:
一个不带 name
的 <slot>
出口会带有隐含的名字“default”。
父组件:
<template>
<div>
<h1>solt</h1>
<Children>
<template v-slot:header></template>
//<template v-slot:default></template>
<p>我是内容</p>
<template v-slot:footer></template>
</Children>
</div>
</template>
子组件:
<template>
<div>
<h2>我是子组件内容</h2>
<slot name="header">我是header</slot>
//<slot name="default">我是内容</slot>
<slot>我是内容</slot>
<slot name="footer">我是footer</slot>
</div>
</template>
五:作用域插槽
有时让插槽内容能够访问子组件中才有的数据是很有用的。
可以这么来理解作用域插槽:就是在父级组件内的子组件插槽内(<Chinlren>我这个区域就是:子组件插槽内 </Children>),可以访问子组件内的data数据。
父组件:
<template>
<div>
<h1>solt</h1>
<Children v-slot:default="names">
{{ names }}
</Children>
</div>
</template>
子组件:
<template>
<div>
<h2>我是子组件内容</h2>
<slot v-bind:names="names">我是内容</slot>
</div>
</template>
<script>
export default {
data () {
return {
names:"abc"
}
}
}
#独占默认插槽的缩写语法
1:当被提供的内容只有默认插槽时,组件的标签才可以被当作插槽的模板来使用。这样我们就可以把
v-slot
直接用在组件上 。(v-slot可以省略template标签直接写在组件上)
2: 假定未指明的内容对应默认插槽一样,不带参数的
v-slot
被假定对应默认插槽(v-slot:default可以缩写为v-slot)
#解构插槽 Prop
<template>
<div>
<h1>solt</h1>
<Children v-slot:default="{names}">
{{ names }}
</Children>
</div>
</template>
六:动态插槽名
<template v-slot:[name]>
</template>
七:具名插槽的缩写
v-slot:header缩写为:#header
八:其他
示例:
父组件:
<template>
<div>
<h1>solt</h1>
<Children>
<template v-slot:todo="{todo}">
<span v-if="todo.flag">{{todo.age}}</span>
</template>
</Children>
</div>
</template>
子组件:
<template>
<div>
<h2>我是子组件内容</h2>
<ul>
<li v-for="todo in arrs" :key="todo.age">
<slot name="todo" v-bind:todo="todo">
{{ todo.name }}
</slot>
</li>
</ul>
</div>
</template>
<script>
export default {
data () {
return {
arrs:[
{
name:"zhangsan",
age:31,
flag:true
},
{
name:"wangwu",
age:18,
flag:false
},
{
name:"zhaoliu",
age:20,
flag:true
}
]
}
}
}
</script>
参考官方 https://cn.vuejs.org/v2/guide/components-slots.html#%E5%85%B6%E5%AE%83%E7%A4%BA%E4%BE%8B
完结。
欢迎关注小程序,感谢您的支持!
三毛
2020年6月24日 上午10:27
写的很不错哟,继续加油!