让你彻底理解Vue插槽本质~
基本使用
// App.vue
<template>
<Comp>
<p>default slot</p>
<template v-slot:slot1>
<p>slot1</p>
</template>
<template #slot2="{ msg }" >
<p>slot2:{{ msg }}</p>
</template>
<template v-slot:customSlot>
<p>slot3</p>
</template>
</Comp>
</template>
<script setup>
import Comp from './Comp.vue'
</script>
// Comp.vue
<template>
<div>
<slot></slot>
<slot name="slot1"></slot>
<slot name="slot2" msg="hello world"></slot>
<slot :name="slotName">
<!-- 默认插槽内容 -->
默认插槽内容
</slot>
</div>
</template>
<script setup>
import { ref } from 'vue'
const slotName = ref('defaultSlot');
</script>
插槽的使用分为三大类,上面的代码均有体现怎么使用:
- 默认插槽
- 具名插槽
- 动态插槽名
解析本质
我们把组件以js
的形式暴露:
// Comp.js
import { createElementVNode } from 'vue'
export default {
setup(props, { slots }) {
console.log(slots);
return () => {
return createElementVNode('div', null, []);
};
},
};
这里不了解createElementVNode
的同学可以认作是创造了虚拟节点,我们看一看slots
的打印结果:
我们可以看到:
slot
本质是Proxy
代理的对象- 在Target里,里面进行插槽的设置本质都是函数形式的调用
我们再看看调用了该函数会发生什么:
// Comp.js
import { createElementVNode } from 'vue'
export default {
setup(props, { slots }) {
const _default = slots.default();
console.log(_default);
return () => {
return createElementVNode('div', null, []);
};
},
};
很明显,是一个虚拟Dom节点对象。
完整实现的代码:
// Comp.js
import { createElementVNode } from 'vue'
export default {
setup(props, { slots }) {
const _default = slots.default();
const _slot1 = slots.slot1();
const _slot2 = slots.slot2({ msg: 'hello' });
const _slotName = slots.customSlot();
return () => {
return createElementVNode('div', null, [
..._default,
..._slot1,
..._slot2,
..._slotName
]);
};
},
};
总结
- Vue 插槽的本质就是进行函数的调用
- 无论是默认插槽、具名插槽和动态插槽名,其本质就是在用
proxy
进行代理的slots
对象上添加函数方法,在父组件里进行了函数的调用,创造出对应的虚拟节点
转载自:https://juejin.cn/post/7258582103326752824