基础-vue插槽的本质

73 阅读1分钟

官网文档,对插槽做出相关的定义,例如默认插槽、具名插槽和作用域插槽。现在用另一种方式来解析插槽的本质。

//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, []); // 创建虚拟节点
    };
  },

image.png 获取 slots属性。

setup(props, { slots }) {
    console.log("slots", slots);
    return () => {
      return createElementVNode("div", null, []); // 创建虚拟节点
    };
  },

image.png 这就对上了,在使用插槽的时候,就是传了一个对象过去。

使用插槽,即函数调用。

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