今天团队内部有一个技术分享会,主要是vue进阶这一块,我对插槽slot的认识还不清晰,于是就总结一下
什么是插槽?
插槽(Slot)是Vue提出来的一个概念,正如名字一样,插槽用于决定将所携带的内容,插入到指定的某个位置,从而使模板分块,具有模块化的特质和更大的重用性。
插槽显不显示、怎样显示是由父组件来控制的,而插槽在哪里显示就由子组件来进行控制
从 vue@2.6.x 开始,Vue 为具名和范围插槽引入了一个全新的语法,即我们今天要讲的主角:v-slot 指令。目的就是想统一 slot 和 slot-scope 语法,使代码更加规范和清晰。既然有新的语法上位,很明显,slot 和 scope-slot 也将会在 vue@3.0.x 中彻底的跟我们说拜拜了。而从 vue@2.6.0 开始,官方推荐我们使用 v-slot 来替代后两者。
跟 v-on 和 v-bind 一样,v-slot 也有缩写,即把参数之前的所有内容 (v-slot:) 替换为字符 #。例如 v-slot:header 可以被重写为 #header:
下面我们将用之前的slot的默认插槽,具名插槽,作用域插槽 和最新的v-slot做对比记忆
怎么用插槽?
1.默认插槽
1.1 老的写法
子组件(slotOne1)
<template>
<div class="slotOne1">
<div>我是slotOne1组件</div>
<slot></slot>
</div>
</template>
在子组件中写入slot,slot所在的位置就是父组件要显示的内容
父组件
<template>
<div>
我是父组件
<slotOne1>
<p style="color:red">我是父组件插槽内容</p>
</slotOne1>
</div>
</template>
在父组件引用的子组件中写入想要显示的内容(可以使用标签,也可以不用)

1.2 用v-slot实现(新的方法)
子组件(slotOne1)
<template>
<div class="slotOne1">
<div>我是slotOne1组件</div>
<slot></slot>
</div>
</template>
在子组件中写入slot,slot所在的位置就是父组件要显示的内容
父组件
<template>
<div>
我是父组件
// 当然也可以不写v-slot:default 直接<slotOne1>
<slotOne1 v-slot:default>
<p style="color:red">我是父组件插槽内容</p>
</slotOne1>
</div>
</template>
Tips: 没有名字的 隐含有一个 “default” 名称
任何没有被包裹在带有 v-slot 的 组件标签 中的内容都会被视为默认插槽的内容。
在父组件引用的子组件中写入想要显示的内容(可以使用标签,也可以不用)

当然在父组件引用的子组件中也可以写入其他组件 例如:
子组件(slotOne1)
<template>
<div class="slotOne1">
<div>我是slotOne1组件</div>
<slot></slot>
</div>
</template>
子组件(slotOne2)
<template>
<div class="slotOne2">
我是slotOne2组件
</div>
</template>
父组件
<template>
<div>
我是父组件
<slotOne1>
<p style="color:red">我是父组件插槽内容</p>
<slot-one2></slot-one2>
</slotOne1>
</div>
</template>

2.具名插槽
2.1 老的写法
子组件(slotTwo)
<template>
<div class="slottwo">
<div>slottwo</div>
<slot name="header"></slot>
<slot></slot>
<slot name="footer"></slot>
</div>
</template>
在子组件中定义了三个slot标签,其中有两个分别添加了name属性header和footer
父组件
<template>
<div>
我是父组件
<slot-two>
<p>啦啦啦,啦啦啦,我是卖报的小行家</p>
<template slot="header">
<p>我是name为header的slot</p>
</template>
<p slot="footer">我是name为footer的slot</p>
</slot-two>
</div>
</template>
在父组件中使用template并写入对应的slot值来指定该内容在子组件中现实的位置(当然也不用必须写到template),没有对应值的其他内容会被放到子组件中没有添加name属性的slot中

2.2 新的写法
子组件(slotTwo)
<template>
<div class="slottwo">
<div>slottwo</div>
<slot name="header"></slot>
<slot></slot>
<slot name="footer"></slot>
</div>
</template>
在子组件中定义了三个slot标签,其中有两个分别添加了name属性header和footer
父组件
<template>
<div>
我是父组件
<slot-two>
<template #header>
<p>我是name为header的slot</p>
</template>
//<p>啦啦啦,啦啦啦,我是卖报的小行家</p> // 不用template标签也可以 会添加到默认插槽中
<template #default>
<p>啦啦啦,啦啦啦,我是卖报的小行家</p>
</template>
// 请注意, v-slot 只能添加到 <template> 或自定义组件上,这点与弃用的 slot 属性不同 这里使用了缩写# v-slot的缩写是#
//<p #footer>我是name为footer的slot</p> 不能这样写
// 要这样写
<template #footer>
<p>我是name为footer的slot</p>
</template>
</slot-two>
// 或者用以下的格式
<slot-two>
<template v-slot:header>
<p>我是name为header的slot</p>
</template>
<template v-slot:default>
<p>啦啦啦,啦啦啦,我是卖报的小行家</p>
</template>
<template v-slot:footer>
<p>我是name为footer的slot</p>
</template>
</slot-two>
</div>
</template>
请注意, v-slot 只能添加到 或自定义组件上,这点与弃用的 slot 属性不同 v-slot:的缩写是#
还有就是要么都用v-slot: 要么都用缩写#,不要混合用,要不然只有最后面的才生效
在父组件中使用template并写入对应的slot值来指定该内容在子组件中现实的位置(当然也不用必须写到template),没有对应值的其他内容会被放到子组件中没有添加name属性的slot中
展示插槽的默认内容
子组件(slotTwo2)
<template>
<div class="slottwo">
<slot>啦啦啦,啦啦啦,我是卖报的小行家</slot>
</div>
</template>
父组件
<template>
<div>
我是父组件
<slot-two2></slot-two2>
</div>
</template>

编译作用域
子组件(slotThree)
<template>
<div class="slotthree">
<slot></slot>
</div>
</template>
父组件
<template>
<div>
我是父组件
<slot-three>
<p>{{name}}</p>
</slot-three>
</div>
</template>
<script>
export default {
data () {
return {
name: 'Jack'
}
}
}
</script>

3.作用域插槽
3.1 老的写法
子组件(slotFour)
<template>
<div>
我是作用域插槽的子组件
<slot :data="user"></slot>
</div>
</template>
<script>
export default {
name: 'slotfour',
data () {
return {
user: [
{name: 'Jack', sex: 'boy'},
{name: 'Jone', sex: 'girl'},
{name: 'Tom', sex: 'boy'}
]
}
}
}
</script>
在子组件的slot标签上绑定需要的值
父组件
<template>
<div>
我是作用域插槽
<slot-four>
<template slot-scope="user">
<div v-for="item in user.data" :key="item.id">
// item in user.data这里的user.data中的data一定是要加的,不加显示不出来 谨记
{{item}}
</div>
</template>
</slot-four>
</div>
</template>
在父组件上使用slot-scope属性,user.data就是子组件传过来的值

3.2 新的写法
子组件(slotFour)
<template>
<div>
我是作用域插槽的子组件
<slot :data="user"></slot>
</div>
</template>
<script>
export default {
name: 'slotfour',
data () {
return {
user: [
{name: 'Jack', sex: 'boy'},
{name: 'Jone', sex: 'girl'},
{name: 'Tom', sex: 'boy'}
]
}
}
}
</script>
在子组件的slot标签上绑定需要的值
父组件
<template>
<div>
我是作用域插槽
<slot-four>
//<template v-slot:default="user"> 也可以这样写,下面是简写 v-slot 和 v-shot:default 是一样的效果。但当遇到缩写形式时需要显示调用。
<template v-slot="user">
<div v-for="item in user.data" :key="item.id">
{{item}}
</div>
</template>
</slot-four>
</div>
</template>
user.data就是子组件传过来的值

感谢这篇文章的帮助vue中的插槽————slot
有一篇文章写的不错Vue.js 你需要知道的 v-slot (译)
本文介绍了Vue中的插槽机制,包括默认插槽、具名插槽、作用域插槽及其在vue@2.6.x后的v-slot新语法。通过示例展示了如何使用v-slot替代老的slot和slot-scope,强调了v-slot的使用规则以及其在模板分块和组件重用中的重要性。

3679

被折叠的 条评论
为什么被折叠?



