如何简单明了使用slot插槽
在官网已经表明如何使用,但我觉得看的有点小乱,本文章记录一下,也是整理自己的思路
使用solt的理由:在不同的组件使用,它最核心的地方展示是不一样的,但其它的地方是一样的,只是数据不一样。也就是说只有在不一样的地方才使用slot插槽
如果子组件不使用slot插槽的情况下,在父组件里面写内容是不会渲染的。
目录
2.2、[key: string]: any参数 以及 作用域插槽
1、简单使用slot插槽
在A文件定义,定义slot插槽
<template>
<div>
<slot></slot>
</div>
</template>
在B文件使用,使用slot插槽
<template>
<soltA>
//使用slot
<div class="box">要写的内容</div>
</soltA>
</template>
<script setup lang='ts'>
//引入组件
import soltA from './a.vue';
</script>
就是最简单的slot插槽使用
2、默认插槽和具名插槽、动态插槽名
slot插槽有两种参数,一个是name,定义插槽名
第二个是[key: string]: any ,与它一起用的还有作用域插槽
注意:
一旦使用多个slot,只有一个可以不写name(不写的默认是default),也就是默认插槽,
其它的slot都要写name属性,否则会重复渲染,也就是具名插槽
2.1、name参数:默认插槽和具名插槽
先说第一个参数 name , 它是默认插槽和具名插槽的分界线,用代码来说
在A文件定义,定义slot插槽
<template>
<div class="container">
<header>
<!-- 标题内容放这里 -->
<slot name="header"></slot>
</header>
<main>
<!-- 主要内容放这里 -->
<slot></slot>
</main>
<footer>
<!-- 底部内容放这里 -->
<slot name="footer"></slot>
</footer>
</div>
</template>
在B文件使用,使用slot插槽
同时定义多个slot时,要使用template 组件,如果不使用,就默认渲染在没写名的solt上,也就是 default ( 默认插槽 ) 。
#的全名是v-slot,一般我们都是使用#号
<template #defaule>其意思就是“将这部分模板片段传入子组件的 name 为 header 插槽中”。
<template>
<soltA>
<template #footer>
<div class="box">底部内容放这里</div>
</template>
<template #header>
<div class="box">标题内容放这里</div>
</template>
<template #default>
<div class="box">主要内容放这里</div>
</template>
</soltA>
</template>
观察下面并结合上面,你会发现,
渲染的位置关键不是在使用slot的位置,而是在 name 定义的位置
这点很重要,因为的使用的时候改不了它的渲染的位置
2.2、[key: string]: any参数 以及 作用域插槽
使用 [key: string]: any,与它一起用的还有作用域插槽
使用场景:数据经过一定处理,然后返回给组件使用
在A文件定义,定义slot插槽( [key: string]: any参数 )
<template>
<div class="container">
<slot :item ='item' :data="data"></slot>
</div>
</template>
<script setup lang='ts'>
import { ref } from 'vue'
let item = ref([
{
name:'张三',
age:18,
},
{
name:'李四',
age:28,
}
])
let data = ref(999)
</script>
在B文件使用,使用slot插槽 ( 作用域插槽 )
在父组件使用 template 组件上使用#xxx="{ xxx , xxx}"接受数据,使用ES6{}解构数据更好,如果好奇不使用是怎么样的,可以复制删除括号试下
<template>
<soltA>
<template #default="{ item , data }" class="box">
<div v-for="i in item">
姓名:{
{i.name}}
年龄:{
{i.age}}
money:{
{data}}
</div>
</template>
</soltA>
</template>
<script setup lang="ts">
import soltA from "./a.vue";
</script>
2.3、动态插槽名
这个对我们这些普通开发并不实用,而且还有限制,只是官方所有指令都支动态绑定而已
使用
<template>
<template v-slot:[dynamicSlotName]>
...
</template>
<!-- 缩写为 -->
<template #[dynamicSlotName]>
...
</template>
<!-- 错误写法:动态参数语法的限制 -->
<template #['foo' + bar]> ... </template >
</template>
如果你需要传入一个复杂的动态参数,官方推荐使用计算属性替换复杂的表达式
3、无渲染组件
这个官方说的也很明确了,我就不再多写别的了
无渲染组件的概念是:在子组件或slot的组件上不写任何元素,不做任何渲染,只处理数据或逻辑
官方案例:在A文件定义,定义slot插槽
<template>
<slot :x="x" :y="y"/>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
const x = ref(0)
const y = ref(0)
const update = e => {
x.value = e.pageX
y.value = e.pageY
}
onMounted(() => window.addEventListener('mousemove', update))
onUnmounted(() => window.removeEventListener('mousemove', update))
</script>
在B文件使用,使用slot插槽
<template>
<MouseTracker v-slot="{ x, y }">
Mouse is at: {
{ x }}, {
{ y }}
</MouseTracker>
</template>
<script setup>
import MouseTracker from './MouseTracker.vue'
</script>
这个是官方案例是根据鼠标的位置来展示它的XY值
4、插槽选择器
这个功能是来至vue3单文件组件CSS 功能
使用场景:定义特定的class类名,到父组件直接使用,不用每次调用该组件时再次重复写这类名的样式
简单来说,就是子组件是默认修改不了父组件有样式,而插槽选择器可以在子组件中选中父组件slot的元素
在A文件定义,定义slot插槽
<template>
<div class="container">
<slot :item ='item' :data="data"></slot>
</div>
</template>
<style lang='less' scoped>
//修改父组件的 .slot-div 的样式
:slotted(.slot-div){
color: red;
}
</style>
在B文件使用,使用slot插槽
<template>
<soltA>
<template #default>
<div class="slot-div">在使用slot,它的类名是slot-div</div>
<div>它的没有类名</div>
</template>
</soltA>
</template>
<script setup lang="ts">
import soltA from "./a.vue";
</script>
到这我们已经把slot插槽基础学完了