Vue插槽的作用

1. 默认插槽

概述:

当子组件模板只有一个没有属性的插槽时,父组件传入的整个内容片段将插入到插槽所在的 DOM 位置,并替换掉插槽标签本身。

使用:

父组件:

<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>

子组件:

<template>
 <div>
 <h3>child组件</h3>
 <!-- 声明位置,用于在调用此组件为双标签时,中间内容显示的位置 -->
 <!-- 单个插槽,一个组件只能有一个默认插槽 -->
 <!-- <slot name="default"></slot> -->
 <!-- 简写 -->
 <slot>默认</slot>
 </div>
</template>
<script>
export default {
 data() {
 return {}
 },
 methods: {}
}
</script>
<style lang="scss" scoped></style>

2. 具名插槽

概述:

有时我们需要多个插槽,来完成对应的数据自定义显示。一个不带 name 的 <slot> 插槽会带有隐含的名字“default”,即默认插槽。带 name 即为具名插槽。

使用:

父组件:

<template>
 <div>
 <h3 class="title">App组件</h3>
 <hr />
 <child>
 <!-- 具名插槽 -->
 <!-- vue2.6之前写法 -- 重复调用会依次执行显示,即都会显示 -->
 <!-- <h3 slot="header">我是文章标题1</h3> -->
 <!-- <h3 slot="header">我是文章标题2</h3> -->
 <!-- <h3 slot="header">我是文章标题3</h3> -->
 <!-- vue2.6及之后写法 它只能写在template中,不能直接写在html标签上 -->
 <!-- vue2.6之后的具名插槽,重复调用,只会执行最后1次 -->
 <!-- <template v-slot:header> -->
 <!-- 简写:v-slot:header == #header -->
 <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>

子组件:

<template>
 <div>
 <h3>child组件</h3>
 <!-- 具名插槽,给slot添加一个名称,名称不能重复 -->
 <slot name="header">默认头部</slot>
 <!-- 默认插槽 -->
 <slot>默认</slot>
 </div>
</template>
<script>
export default {
 data() {
 return {}
 },
 methods: {}
}
</script>
<style lang="scss" scoped></style>

3. 作用域插槽

概述:

作用域插槽是一种特殊类型的插槽,用作一个 (能被传递数据的)可重用模板,来代替已经渲染好的元素。在子组件中,只需将数据传递到插槽,就像你将 prop 传递给组件一样。

在封装组件的过程中,可以为预留的<slot>插槽绑定props 数据,这种带有props 数据的 <slot> 叫做“作用域插槽”。作用域插槽就是在具名插槽的基础上,多了数据的传递。

语法:

# 子组件中
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>

使用:

父组件:

<template>
 <div>
 <h3 class="title">App组件</h3>
 <hr />
 <child :users="users">
 <!-- vue2.6之前的写法 -->
 <!-- <button slot="del" slot-scope="index" @click="del(index)">删除</button> -->
 <!-- vue2.6之后的写法 -->
 <!-- <template v-slot:del="index">,即<template v-slot:[变量]="index">-->
 <!-- vue2.6之后的写法简写 -->
 <!-- 父组件接收子组件通过作用于插槽传过来的index -->
 <template #del="index">
 <!-- 把子组件中的span标签替换为了button标签 -->
 <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: {
 // 传过来的index是一个对象,所以需要解构一下
 del({ index }) {
 console.log("app", index);
 },
 },
};
</script>
<style lang="scss" scoped></style>

子组件:

<template>
 <div>
 <h3>child组件</h3>
 <hr />
 <ul>
 <li v-for="(item, index) in users" :key="item.id">
 <span>
 {{ item.name }}
 </span>
 <span>
 <!-- 让插槽传数据 作用域插槽 -->
 <!-- 子组件将index通过作用域插槽传给父组件 -->
 <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>

作者:月光晒了很凉快原文地址:https://blog.csdn.net/weixin_45605541/article/details/126901158

%s 个评论

要回复文章请先登录注册