Vue递归组件的slot传递

在递归组件中,根组件的写的slot,递归生成的组件无法渲染。经过研究后可采用子组件递归获取根组件,并对应渲染slot达到预期效果。

组件结构
//调用组件的index.vue
<LeeTable>
	     <template #date="{ row }"></template>
	     
	     <template #date2="{ row }"></template>
<LeeTable>

//leeTable main.vue
<el-table>	
  <template v-for="(column, columnIndex) in (columns)">
  	//递归组件 Column
  	<Column :column="column"></Column>
  </template>
</el-tbale>

//递归组件Column
<el-table-column>
    <!-- 多级表头递归组件 -->
    <template v-if="hasSub" #default="scope">
      <Column :column="subColumn" v-for="subColumn in column.childs" childs>
      </Column>
    </template>
		<!-- 没有childs -->
    <template v-if="isDefault" #default="scope">
	    <template v-if="column.slotName">
        //...渲染模版 渲染slots 见下文
      </template>
			//...业务代码
    </template>
</el-table-column>
获取根组件方法
//tool.ts
import { ComponentInternalInstance } from 'vue'

const rootComponentName = 'LeeTable' //根节点Name
/**
 * @description 获取根节点
 * @param {ComponentInternalInstance} component 当前节点
 * @returns 根节点
 */
export const getRootComponent = (component: ComponentInternalInstance | null): ComponentInternalInstance | null => {
  //若当前节点已是根节点 则直接返回当前节点
  if (component && component.type.name === rootComponentName) {
    return component
  }
  //当前节点有节点 递归查询 找到根节点
  if (component && component.parent) {
    const parent = component.parent
    return getRootComponent(parent)
  }
}
渲染模板
//templateSlot.vue
import { h } from "vue";
export default {
    functional: true,
    props: {
        template: {
            type: Function,
        },
        data: {
            type: Object,
        },
    },
    render: (props: any, ctx: any) => {
        return h("div", [props.template(props.data)]);
    },
}
使用并渲染
//递归组件Column
<el-table-column>
    <!-- 多级表头递归组件 -->
    <template v-if="hasSub" #default="scope">
      <Column :column="subColumn" v-for="subColumn in column.childs" childs>
      </Column>
    </template>
		<!-- 没有childs -->
    <template v-if="isDefault" #default="scope">
	    <template v-if="column.slotName">
        //使用渲染模板渲染slot
        <templateSlot v-if="nodeTemplate" :template="nodeTemplate" :data="scope" :row="scope.row">
        </templateSlot>
      </template>
			//...业务代码
    </template>
</el-table-column>

//递归组件Column.vue
<script lang="ts" setup>
import { getRootComponent } from "./tool";
import { computed, getCurrentInstance, h } from "vue";
import TemplateSlot from "./templateSlot";

//获取根节点
const leeTable = getRootComponent(getCurrentInstance());
//根节点slots
const parentSlots = leeTable?.slots;
//获取当前列对应slots
const nodeTemplate = parentSlots[column.slotName] as any;
</script>
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值