官网文档,对插槽做出相关的定义,例如默认插槽、具名插槽和作用域插槽。现在用另一种方式来解析插槽的本质。
//comp.vue
<template>
<div>
<slot></slot>
<slot name="slot1"></slot>
<slot name="slot2" msg="hello"></slot>
</div>
</template>
//index.vue
<Comp>
<p>默认插槽</p>
<template #slot1>
<p>具名插槽</p>
</template>
<template #slot2="{ msg }">
<p>作用域插槽:{{ msg }}</p>
</template>
</Comp>
可以理解为在使用 Comp时,传了一个对象过去,这个对象有三个属性,属性值是 函数。
{
default:function(){},
slot1:function(){},
slot2:function(){}
}
相当于在组件里写 <slot></slot>,是在调用上述对象里的default方法。
手写一个.js文件来实现插槽的效果。
//comp.js
import { createElementVNode } from "vue";
export default {
setup() {
return () => {
return createElementVNode("div", null, []); // 创建虚拟节点
};
},
};
获取传入的参数。
setup(props, ctx) { //两个参数 第二个参数包含了一些其他信息
console.log("ctx", ctx);
return () => {
return createElementVNode("div", null, []); // 创建虚拟节点
};
},
获取
slots属性。
setup(props, { slots }) {
console.log("slots", slots);
return () => {
return createElementVNode("div", null, []); // 创建虚拟节点
};
},
这就对上了,在使用插槽的时候,就是传了一个对象过去。
使用插槽,即函数调用。
setup(props, { slots }) {
const defaultVNode = slots.default(); // 调用默认方法
return () => {
return createElementVNode("div", null, [...defaultVNode]);
};
},
完整代码:
//comp.js
import { createElementVNode } from "vue";
export default {
setup(props, { slots }) {
const defaultVnode = slots.default(); // 调用默认方法
const slot1Vnode = slots.slot1();
const slot2Vnode = slots.slot2({
msg: "hello",
});
return () => {
return createElementVNode("div", null, [
...defaultVnode,
...slot1Vnode,
...slot2Vnode,
]);
};
},
};