欢迎光临
我们一直在努力

2、v-slot插槽

v-slot插槽

  • 具名插槽
  • 条件插槽
  • 动态插槽
  • 作用域插槽

<template>
<div>
<!– 内部的内容不会被渲染 –>
<my-child>
<p>这是一段文字</p>
<!– … –>
</my-child>
</div>
</template>

<script>
import MyChild from "@/pages/MyChild.vue"
export default {
components: {
MyChild
},
}
</script>

插槽:子组件留给父组件的内容占位符,父组件可以把任意内容(文本、HTML、其他组件)塞进这个占位符里,而子组件负责决定这个占位符的位置和样式

  • 第一步:内部的内容建议都套在一个template标签内

<!– App.vue –>
<template>
<div>
<my-child>
<!– 建议将内部内容都先套在一个大template标签内 –>
<template>
<p>这是一段文字</p>
<div>这是一个div</div>
<!– … –>
</template>
</my-child>
</div>
</template>

  • 第二步:内部的内容是在子组件MyChild组件内,即这个内部内容欲被渲染到子组件MyChild组件内,但是渲染到子组件的哪里,使用插槽slot标签

<!– MyChild.vue –>
<template>
<div>
<!– slot标签内就把内部内容渲染到slot标签占位处 –>
<slot></slot>
<h3>这是MyChild</h3>
<slot></slot>
</div>
</template>

具名插槽

具名插槽:内部内容不一定全部都占位于slot标签,如果内部内容需要一部分放在子组件中的一个地方,另一部分放在子组件中另一个地方等等,使用具名插槽

  • 第一步:给每个slot占位符赋name属性,表示该slot所占位的区域只能由template标签v-slot动态绑定内的相应内容的渲染

<!– MyChild.vue –>
<template>
<div>
<!– slot标签内就把内部内容渲染到slot标签占位处 –>
<slot name="before"></slot>
<h3>这是MyChild</h3>
<slot name="after"></slot>
</div>
</template>

  • 第二步:template标签使用v-slot动态绑定相应区域的内容

<template v-slot:名称>…</template>
<template #名称>…</template>

<!– App.vue –>
<template>
<div>
<my-child>
<!– 建议将内部内容都先套在一个大template标签内 –>
<template #after>
<p>这是一段文字</p>
<div>这是一个div</div>
<!– … –>
</template>
<template v-slot:before>
<p>这是一段文字</p>
<div>这是一个div</div>
<!– … –>
</template>
</my-child>
</div>
</template>

条件插槽

条件插槽:条件插槽 = 插槽 + v-if/v-else,让插槽内容 “按需显示”

注意:不能配合v-show使用,使用v-show(display:none)隐藏元素,无法作用于template标签上

<!– MyChild.vue –>
<template>
<div>
<h3>这是MyChild组件</h3>
<!– 当div内无内容时,外层div将不会被渲染 –>
<div v-if="$slots.content">
<slot name="content"></slot>
</div>
</div>
</template>

<!– App.vue –>
<template>
<div>
<my-child>
<template #content v-if="status === '已下单'">
<button>催发货</button>
</template>
<template #content v-if="status === '已发货'">
<button>查看物流</button>
</template>
<template #content v-if="status === '待签收'">
<button>查看取件码</button>
</template>
<template #content v-if="status === '待评价'">
<button>请评价</button>
</template>
</my-child>
<input type="radio" v-model="status" value="已下单" name="status">已下单
<input type="radio" v-model="status" value="已发货" name="status">已发货
<input type="radio" v-model="status" value="待签收" name="status">待签收
<input type="radio" v-model="status" value="待评价" name="status">待评价
</div>
</template>

<script>
import MyChild from "@/pages/MyChild.vue";
import { ref } from "vue";
export default {
components: {
MyChild
},
setup() {
let status = ref("已下单");
return {
status
}
}
}
</script>

动态插槽

动态插槽:插槽名称不是固定的,由变量动态决定

<template v-slot:[变量名]>…</template>
<template #[变量名]>…</template>

<!– MyChild.vue –>
<template>
<div>
<header>
header:<slot name="header"></slot>
</header>
<main>
content:<slot name="content"></slot>
</main>
<footer>
footer:<slot name="footer"></slot>
</footer>
</div>
</template>

<!– App.vue –>
<template>
<div>
<button @click="selectedSlot = 'header'">插入到头部</button>
<button @click="selectedSlot = 'content'">插入到内容区</button>
<button @click="selectedSlot = 'footer'">插入到脚部</button>
<my-child>
<template v-slot:[selectedSlot]>
<span>
这段内容会动态插入到<strong>{{ selectedSlot }}</strong>插槽中
</span>
</template>
</my-child>

</div>
</template>

<script>
import MyChild from "@/pages/MyChild.vue";
import { ref } from "vue";
export default {
components: {
MyChild
},
setup() {
let selectedSlot = ref('header')
return {
selectedSlot
}
}
}
</script>

作用域插槽

作用域插槽:让父组件在填充插槽内容时,能够访问到子组件内部的数据

<!– App.vue –>
<template>
<div>
<my-child>
<template #content>
<!– Property "childData" was accessed during render but is not defined on instance. –>
<h3 style="color: #f00;">{{ childData }}</h3>
</template>
</my-child>
</div>
</template>

<!– MyChild.vue –>
<template>
<div>
<h3>{{ childData }}</h3>
<slot name="content"></slot>
</div>
</template>

<script>
export default {
setup() {
const childData = "这是子组件的数据…"
return {
childData
}
}
}
</script>

  • 第一步:子组件对外暴露数据,通过v-bind将数据绑定到动态属性上
  • 第二步:父组件通过v-slot:插槽名=“数据对象”接收子组件暴露的数据

<!– App.vue –>
<template>
<div>
<my-child>
<!– 父组件通过v-slot:名称="数据对象",接收传递过来的数据对象,通过数据对象.子组件对外暴露的属性名访问子组件的数据 –>
<template #content="slotProps">
<!– Property "childData" was accessed during render but is not defined on instance. –>
<!– <h3 style="color: #f00;">{{ childData }}</h3> –>
<h3 style="color: #f00;">{{ slotProps.dataFromChild }}</h3>
</template>
</my-child>
</div>
</template>

<!– MyChild.vue –>
<template>
<div>
<h3>{{ childData }}</h3>
<!– 通过动态绑定属性v-bind将数据childData以名为dataFromChild的属性暴露出去 –>
<slot name="content" :dataFromChild="childData"></slot>
</div>
</template>

<script>
export default {
setup() {
const childData = "这是子组件的数据…"
return {
childData
}
}
}
</script>

赞(0)
未经允许不得转载:171主机测评 » 2、v-slot插槽
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址