Vue中插槽的使用备忘
插槽(slot)是 Vue 为组件的封装者提供的能力。
允许开发者在封装组件时,把不确定的、希望由用户指定的部分,
定义为插槽。可以把插槽认为是组件封装期间,为用户预留的占位符
参考链接
1. 默认插槽
当子组件模板只有一个没有属性的插槽时,
父组件传入的整个内容片段将插入到插槽所在的 DOM 位置,
并替换掉插槽标签本身
1-1 实例:父组件
<template>
<div>
<h3 class="title">App组件</h3>
<hr />
<child>
<h3>我是标题</h3>
</child>
<child />
<child></child>
</div>
</template>
<script>
import child from './components/child.vue'
export default {
components: {
child
},
data() {
return {}
},
methods: {}
}
</script>
<style lang="scss" scoped></style>
1-2 实例:子组件
<template>
<div>
<h3>child组件</h3>
<slot>默认</slot>
</div>
</template>
<script>
export default {
data() {
return {}
},
methods: {}
}
</script>
<style lang="scss" scoped></style>
1-3 实例:页面效果
2. 具名插槽
有时页面需要多个插槽,来完成对应的数据自定义显示。
一个不带 name 的 <slot> 插槽会带有隐含的名字“default”,即默认插槽。
指定name属性值的,即为具名插槽 -- 相当于给插槽自己起名字
2-1 实例:父组件
<template>
<div>
<h3 class="title">App组件</h3>
<hr />
<child>
<template #header>
<h3>我是文章标题1</h3>
</template>
<template #header>
<h3>我是文章标题2</h3>
</template>
<template #header>
<h3>我是文章标题3</h3>
</template>
<div>默认插槽</div>
</child>
</div>
</template>
<script>
import child from './components/child.vue'
export default {
components: {
child
},
data() {
return {}
},
methods: {}
}
</script>
<style lang="scss" scoped></style>
2-2 实例:子组件
<template>
<div>
<h3>child组件</h3>
<slot name="header">默认头部</slot>
<slot>默认</slot>
</div>
</template>
<script>
export default {
data() {
return {}
},
methods: {}
}
</script>
<style lang="scss" scoped></style>
2-3 实例:页面效果
3. 作用域插槽 – 向使用者传递数据
作用域插槽是一种特殊类型的插槽,
能被传递数据的可重用模板,来代替已经渲染好的元素。
在子组件中,只需将数据传递到插槽,就像将 prop 传递给组件一样。
在封装组件的过程中,可以为预留的<slot>插槽绑定props 数据,
这种带有props 数据的 <slot> 叫做“作用域插槽”。
作用域插槽就是在具名插槽的基础上,多了数据的传递
3-1 使用语法
# 子组件中
Vue.component('child', {
template: `
<div class="child">
<slot name="default" text="我是子组件中的内容"></slot>
</div>
`
})
# 父组件中
<div class="parent">
<child>
// 老写法
<div name="default" slot-scope="props">
<div>父组件</div>
<h3>{{ props.text }}</h3>
</div>
// 新写法
<template #default="props">
<div>
<div>父组件</div>
<h3>{{ props.text }}</h3>
</div>
</template>
</child>
</div>
3-2 实例:父组件
<template>
<div>
<h3 class="title">App组件</h3>
<hr />
<child :users="users">
<template #del="index">
<button @click="del(index)">删除</button>
</template>
</child>
</div>
</template>
<script>
import child from "./components/child.vue";
export default {
components: {
child,
},
data() {
return {
users: [
{ id: 1, name: "张三" },
{ id: 2, name: "李四" },
{ id: 3, name: "王五" },
],
};
},
methods: {
del({ index }) {
console.log("app", index);
},
},
};
</script>
<style lang="scss" scoped></style>
3-3 实例:子组件
<template>
<div>
<h3>child组件</h3>
<hr />
<ul>
<li v-for="(item, index) in users" :key="item.id">
<span>
{{ item.name }}
</span>
<span>
<slot name="del" :index="index">
<span @click="del(index)">删除</span>
</slot>
</span>
</li>
</ul>
</div>
</template>
<script>
export default {
props: ['users'],
data() {
return {}
},
methods: {
del(index) {
console.log(index)
}
}
}
</script>
<style lang="scss" scoped></style>
3-4 实例:页面效果