vue实现子组件渲染父级组件的插槽(vue3)

在编写vue通用组件时经常会遇到子组件的插槽需从父组件传递过来,并还可以给插槽绑定数据,如ant-design-vue中的下拉菜单多选项时可以通过插槽自定义tag的内容

先展示下效果:
组件默认效果:
vue实现子组件渲染父级组件的插槽(vue3)_第1张图片

使用了tag插槽的效果:
vue实现子组件渲染父级组件的插槽(vue3)_第2张图片

1、思路

核心思路是:将父组件中的插槽以参数的形式传递给子孙组件,而不是使用插槽传递,如

这里有两种方式可以将父组件的插槽以参数形式传递给子孙组件:

  1. provide+inject形式
  2. 子组件定义props,父组件将slots传递给子组件

这两种方式各有千秋,看自己喜欢了

2、编码:使用 provide+inject 方式实现

父组件





子组件





tag内容组件(如果用jsx可以省略这个组件)

import {
  inject
} from 'vue';

export function MyTagContent (props, ctx) {
  let slot;
  // 获取父级组件传递过来的上下文
  let inputTagsCtx = inject('inputTagsCtx');
  if (inputTagsCtx && inputTagsCtx.slots.tag) {
    // 如果父组件传递了tag插槽则优先使用父组件传递的
    slot = inputTagsCtx.slots.tag;
  } else {
    slot = ctx.slots.default;
  }
  return slot(props.tagData);
};
MyTagContent.props = ['tagData'];

组件调用

3、编码:使用 子组件定义props 方式实现

父组件





子组件





tag内容组件(如果用jsx可以省略这个组件)

export function MyTagContent (props, ctx) {
  let slot;
  if (props.parentSlots.tag) {
    // 如果父组件传递了tag插槽则优先使用父组件传递的
    slot = props.parentSlots.tag;
  } else {
    slot = ctx.slots.default;
  }
  return slot(props.tagData);
};
MyTagContent.props = ['tagData', 'parentSlots'];

组件调用

你可能感兴趣的:(vue实现子组件渲染父级组件的插槽(vue3))