[ slot 插槽 ]
[ slot 有什么用? ]
- 为了复用,在开发过程中,会产生很多组件,组装这些组件会形成一个树形结构。
- 如果组件嵌套层数过多,过于零碎,不利于开发和维护。
- slot 插槽的作用,就是讲组装过程扁平化,比如有三级组件,正常需要在一级组件中嵌入二级组件,在二级组件中嵌入三级组件。而有了插槽,则都可以在一级组件中完成装配。即在一级组件中嵌入二级组件,然后将三级组件插入二级组件的插槽。
- slot 插槽同时也相当于将组件之间进行了解耦。同样一个 header 组件,里面放一个插槽,在正常页面的时候,把导航组件插到里面,而在登陆和注册页面,不插入导航组件即可。这样就不需要准备两套 header 组件。更加灵活。
- 那 slot 组件到底是什么呢?其实就是向组件内部传递组件。在板组件中可能会放置其他组件的地方预留插槽位置,然后在使用板组件的时候,把需要插入到板组件上的组件放入板组件的标签内部即可,多个插槽的时候做好命名即可。
import HeaderView from ...
import NavView from ...
<template>
<header-view>
<nav-view></nav-view> // 插入插槽
</header-view>
</template>
<header>
// logo ...
<slot></slot> // 预留插槽
</header>
// HeaderView.vue
import HeaderView from ...
import NavView from ...
<template>
<header-view>
<template #nav> // 插入到 nav 插槽
<nav-view></nav-view> // 插入插槽
</template>
</header-view>
</template>
<header>
// logo ...
<slot name="nav"></slot> // 预留 nav 插槽
</header>
// HeaderView.vue
[ 数据传递 ]
- 官方在讲这里的时候有点绕,简单来说,这里涉及到三方(机体,板件,插件)之间的数据传递,插件是插入到板件上的组件,板件是安装到机体上的组件。
- 板件是安装到机体上的组件,所以在安装的时候,可以通过 props 的方式将机体的部分数据传入到板件内部,
- 插件是在机体上插入到板件中的,所以这里也可以通过props的方式将机体的部分数据传递给插件。
- 从实际最终结构上来说,插件应该是板件的子组件,那么问题来了,插件怎么获得板件内部的部分数据呢?因为父组件是无法直接获得子组件的数据的,这里机体拿不到板件内部数据,也就无法中转给插件。
- 官方提供了 v-slot 的方式来将数据传递,在前面的案例中,我们使用了 #nav 来在板件上指定要插入那个插槽,这里的 #nav 就是 v-slot="nav" 的简写。
- 通过 #nav="obj" 的方式就可以接受板件内部传递过来的值. 在板件内部的插件接口上,通过属性的方式将值传递给插件即可。
- 这时候在机体内部,我们已经通过 #nav="obj" 的方式拿到板件暴露给我们的数据对象 obj 了,然后通过 props 的方式传递给插件即可,插件内部就可以获得板件内部暴露出来的部分数据了。
// 插件
<script setup>
const props = defineProps({
nav: {
type: Array,
default: ([])
}
})
</script>
<template>
<a
v-for="(link, index) of nav"
:key="index"
:href="`/${link}`"
>{{ link }}</a>
</template>
// 板件
<script setup>
const nav=['home', 'product']
</script>
<template>
<header>
<p>Welcome</p>
<hr>
<slot name="nav" :nav="nav"></slot>
</header>
</template>
// 机体
<script setup>
import HeaderVue from './components/HeaderVue'
import NavVue from './components/NavVue'
</script>
<template>
<header-vue>
<template #nav="{ nav }">
<nav-vue :nav="nav"></nav-vue>
</template>
</header-vue>
</template>
[ 深度选择器 ]
- 在style scope 标签中,我们只能选择当组件内的元素。
- 在使用了第三方插件以后,比如 element-plus,如果要对插件元素内部子元素进行样式设置,就需要用到深度选择器打破壁垒穿透到插件内部进行选择。
:deep(.xxx) {
color: gold;
}