作者接触前端时间较短,对于很多技术的见解还较为浅显。发表文章的初衷也是为了存放一些自己的学习笔记,内容有误的地方希望大家可以批评指正
1.什么是渲染作用域
在讲解作用域插槽之前,需要先引入渲染作用域的概念。例如在如下应用场景,子组件中存在一个变量title,在子组件内部是可以直接访问title的内容的。然而父组件调用子组件时,是无法直接访问子组件中的title的值。因为父级模板里的所有内容都是在父级作用域中编译的,而子组件所有内容都是在子作用域中编译的。
2.作用域插槽的基本理解与使用
上面提到了渲染作用域的问题,然而在很多应用场景下,需要在插槽中访问子组件作用域内的数据。因此作用域插槽的意义在于让插槽可以访问到子组件中的内容 。
通过一个简单的例子说明:ShowName组件接受父组件传入的参数names,随后通过插槽的出口向父组件传递参数。 该子组件的slot向父组件向上传递item与index属性。随后父组件中通过slotProps进行属性的调用。
通过注意:v-slot="xxxx",xxxx的名字并非一定是slotProps,可以自己定义
App.vue
<template>
<div>
<!-- 默认写法 -->
<ShowNames :names="names">
<template v-slot="slotProps">
<span>{{ slotProps.item }} - {{ slotProps.index }}</span>
</template>
</ShowNames>
<ShowNames :names="names">
<template v-slot="showData">
<span>{{ showData.item }} - {{ showData.index }}</span>
</template>
</ShowNames>
</div>
</template>
<script>
import ShowNames from './ShowNames.vue'
export default {
components: {
ShowNames
},
setup () {
const names = ["why", "kobe", "james", "curry"]
return {
names
}
}
}
</script>
<style lang="scss" scoped>
</style>
ShowName.vue
<template>
<div>
<template v-for="(item, index) in names" :key="item">
<slot :item="item" :index="index"></slot>
</template>
</div>
</template>
<script>
export default {
props: {
names: {
type: Array,
default: () => []
}
}
}
</script>
<style scoped>
</style>
3.具名作用域插槽
可以为插槽指定具体的名字。
<template>
<div>
<!-- 具名作用域插槽 -->
<ShowNames :names="names">
<template v-slot:addition="addProps">
<button>{{ addProps.item }}</button>
</template>
</ShowNames>
<!-- 语法糖写法 -->
<ShowNames :names="names">
<template #addition="addProps2">
<strong>{{ addProps2.item }}</strong>
</template>
</ShowNames>
</div>
</template>
<script>
import ShowNames from './ShowNames.vue'
export default {
components: {
ShowNames
},
setup () {
const names = ["why", "kobe", "james", "curry"]
return {
names
}
}
}
</script>
<style lang="scss" scoped>
</style>
<template>
<div>
<template v-for="(item, index) in names" :key="item">
<slot name="addition" :item="item"></slot>
</template>
</div>
</template>
<script>
export default {
props: {
names: {
type: Array,
default: () => []
}
}
}
</script>
<style scoped>
</style>