likes
comments
collection
share

让你彻底理解Vue插槽本质~

作者站长头像
站长
· 阅读数 15

基本使用

让你彻底理解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的打印结果:

让你彻底理解Vue插槽本质~

我们可以看到:

  • 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, []);
        };
    },
};

让你彻底理解Vue插槽本质~

很明显,是一个虚拟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插槽本质~

总结

  • Vue 插槽的本质就是进行函数的调用
  • 无论是默认插槽、具名插槽和动态插槽名,其本质就是在用proxy进行代理的slots对象上添加函数方法,在父组件里进行了函数的调用,创造出对应的虚拟节点