♻️: 重构 renderer
This commit is contained in:
parent
4d807628ab
commit
8820748d8c
@ -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);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
@ -29,7 +29,7 @@ import {
|
|||||||
ElementScrollRect,
|
ElementScrollRect,
|
||||||
DropdownContext,
|
DropdownContext,
|
||||||
} from "./interface";
|
} from "./interface";
|
||||||
import TeleportWrapper from "./TeleportWrapper.vue";
|
import TeleportWrapper from "../_components/teleportWrapper.vue";
|
||||||
|
|
||||||
export type DropdownTrigger = "click" | "hover" | "focus" | "contextMenu";
|
export type DropdownTrigger = "click" | "hover" | "focus" | "contextMenu";
|
||||||
|
|
||||||
|
@ -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);
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
|
@ -17,7 +17,7 @@ import {
|
|||||||
VNodeArrayChildren,
|
VNodeArrayChildren,
|
||||||
StyleValue,
|
StyleValue,
|
||||||
} from "vue";
|
} from "vue";
|
||||||
import Renderer from "./Renderer";
|
import RenderFunction from "../_components/renderFunction";
|
||||||
|
|
||||||
export type SpaceSize = "lg" | "md" | "sm" | "xs" | number | string;
|
export type SpaceSize = "lg" | "md" | "sm" | "xs" | number | string;
|
||||||
|
|
||||||
@ -130,6 +130,6 @@ const renderSpaceItems = () =>
|
|||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div :class="spaceClass" :style="spaceStyle">
|
<div :class="spaceClass" :style="spaceStyle">
|
||||||
<Renderer :renderFn="renderSpaceItems"></Renderer>
|
<RenderFunction :renderFunc="renderSpaceItems" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -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>
|
|
@ -9,6 +9,7 @@ import "./index.less";
|
|||||||
import { LayIcon } from "@layui/icons-vue";
|
import { LayIcon } from "@layui/icons-vue";
|
||||||
import tabItem from "../tabItem/index.vue";
|
import tabItem from "../tabItem/index.vue";
|
||||||
import RenderTitle from "./renderTitle.vue";
|
import RenderTitle from "./renderTitle.vue";
|
||||||
|
import RenderFunction from "../_components/renderFunction";
|
||||||
import {
|
import {
|
||||||
Component,
|
Component,
|
||||||
computed,
|
computed,
|
||||||
@ -23,6 +24,8 @@ import {
|
|||||||
nextTick,
|
nextTick,
|
||||||
CSSProperties,
|
CSSProperties,
|
||||||
reactive,
|
reactive,
|
||||||
|
h,
|
||||||
|
createTextVNode,
|
||||||
} from "vue";
|
} from "vue";
|
||||||
import { useResizeObserver } from "@vueuse/core";
|
import { useResizeObserver } from "@vueuse/core";
|
||||||
import { TabData, TabInjectKey } from "./interface";
|
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);
|
useResizeObserver(navRef, update);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
@ -329,7 +338,7 @@ provide("slotsChange", slotsChange);
|
|||||||
:class="[children.id === active ? 'layui-this' : '']"
|
:class="[children.id === active ? 'layui-this' : '']"
|
||||||
@click.stop="change(children.id)"
|
@click.stop="change(children.id)"
|
||||||
>
|
>
|
||||||
<RenderTitle :tabItemData="children"></RenderTitle>
|
<RenderFunction :renderFunc="renderTabChild(children)" />
|
||||||
<i
|
<i
|
||||||
v-if="allowClose && children.closable != false"
|
v-if="allowClose && children.closable != false"
|
||||||
class="layui-icon layui-icon-close layui-unselect layui-tab-close"
|
class="layui-icon layui-icon-close layui-unselect layui-tab-close"
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
::: demo
|
::: demo
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
<lay-space>
|
||||||
<lay-dropdown updateAtScroll>
|
<lay-dropdown updateAtScroll>
|
||||||
<lay-button type="primary">下拉菜单</lay-button>
|
<lay-button type="primary">下拉菜单</lay-button>
|
||||||
<template #content>
|
<template #content>
|
||||||
@ -23,6 +24,17 @@
|
|||||||
</lay-dropdown-menu>
|
</lay-dropdown-menu>
|
||||||
</template>
|
</template>
|
||||||
</lay-dropdown>
|
</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>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user