♻️: 重构 renderer

This commit is contained in:
sight 2022-08-27 19:20:27 +08:00
parent 4d807628ab
commit 8820748d8c
8 changed files with 48 additions and 58 deletions

View File

@ -0,0 +1,23 @@
import { defineComponent, VNodeTypes } from "vue";
import type { PropType } from "vue";
export type RenderFunc = (props: Record<string, unknown>) => VNodeTypes;
export default defineComponent({
name: "RenderFunction",
props: {
renderFunc: {
type: Function as PropType<RenderFunc>,
default: null,
},
},
setup(props, ctx) {
return () => {
if (typeof props.renderFunc !== "function") {
return null;
}
return props.renderFunc(ctx.attrs);
};
},
});

View File

@ -29,7 +29,7 @@ import {
ElementScrollRect,
DropdownContext,
} from "./interface";
import TeleportWrapper from "./TeleportWrapper.vue";
import TeleportWrapper from "../_components/teleportWrapper.vue";
export type DropdownTrigger = "click" | "hover" | "focus" | "contextMenu";

View File

@ -1,26 +0,0 @@
import { defineComponent } from "vue";
import type { PropType } from "vue";
export default defineComponent({
name: "Renderer",
props: {
renderFn: {
type: Function,
default: null,
},
data: {
type: Object as PropType<Record<string, any>>,
default: undefined,
},
},
setup(props) {
return () => {
if (typeof props.renderFn !== "function") {
return null;
}
return props.renderFn(props.data);
};
},
});

View File

@ -17,7 +17,7 @@ import {
VNodeArrayChildren,
StyleValue,
} from "vue";
import Renderer from "./Renderer";
import RenderFunction from "../_components/renderFunction";
export type SpaceSize = "lg" | "md" | "sm" | "xs" | number | string;
@ -130,6 +130,6 @@ const renderSpaceItems = () =>
</script>
<template>
<div :class="spaceClass" :style="spaceStyle">
<Renderer :renderFn="renderSpaceItems"></Renderer>
<RenderFunction :renderFunc="renderSpaceItems" />
</div>
</template>

View File

@ -1,28 +0,0 @@
<script lang="ts">
import { h, PropType, defineComponent } from "vue";
import { TabData } from "./interface";
export default defineComponent({
name: "RenderTitle",
props: {
tag: {
type: String,
required: false,
default: "span",
},
tabItemData: {
type: Object as PropType<TabData>,
required: false,
},
},
setup(props) {
return props.tabItemData?.slots?.title
? () =>
h(
props.tag,
props.tabItemData?.slots?.title && props.tabItemData?.slots.title()
)
: () => props.tabItemData?.title;
},
});
</script>

View File

@ -9,6 +9,7 @@ import "./index.less";
import { LayIcon } from "@layui/icons-vue";
import tabItem from "../tabItem/index.vue";
import RenderTitle from "./renderTitle.vue";
import RenderFunction from "../_components/renderFunction";
import {
Component,
computed,
@ -23,6 +24,8 @@ import {
nextTick,
CSSProperties,
reactive,
h,
createTextVNode,
} from "vue";
import { useResizeObserver } from "@vueuse/core";
import { TabData, TabInjectKey } from "./interface";
@ -264,6 +267,12 @@ const update = () => {
}
};
const renderTabChild = (child: TabData) => {
return child.slots?.title
? () => h("span", child.slots?.title && child.slots.title())
: () => createTextVNode(child.title);
};
useResizeObserver(navRef, update);
watch(
@ -329,7 +338,7 @@ provide("slotsChange", slotsChange);
:class="[children.id === active ? 'layui-this' : '']"
@click.stop="change(children.id)"
>
<RenderTitle :tabItemData="children"></RenderTitle>
<RenderFunction :renderFunc="renderTabChild(children)" />
<i
v-if="allowClose && children.closable != false"
class="layui-icon layui-icon-close layui-unselect layui-tab-close"

View File

@ -13,6 +13,7 @@
::: demo
<template>
<lay-space>
<lay-dropdown updateAtScroll>
<lay-button type="primary">下拉菜单</lay-button>
<template #content>
@ -23,6 +24,17 @@
</lay-dropdown-menu>
</template>
</lay-dropdown>
<lay-dropdown updateAtScroll popupContainer=".layui-body">
<lay-button type="primary">下拉菜单</lay-button>
<template #content>
<lay-dropdown-menu>
<lay-dropdown-menu-item>选项一</lay-dropdown-menu-item>
<lay-dropdown-menu-item>选项二</lay-dropdown-menu-item>
<lay-dropdown-menu-item>选项三</lay-dropdown-menu-item>
</lay-dropdown-menu>
</template>
</lay-dropdown>
</lay-space>
</template>
<script>