♻️: 重构 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,
 | 
			
		||||
  DropdownContext,
 | 
			
		||||
} from "./interface";
 | 
			
		||||
import TeleportWrapper from "./TeleportWrapper.vue";
 | 
			
		||||
import TeleportWrapper from "../_components/teleportWrapper.vue";
 | 
			
		||||
 | 
			
		||||
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,
 | 
			
		||||
  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>
 | 
			
		||||
 | 
			
		||||
@ -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 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"
 | 
			
		||||
 | 
			
		||||
@ -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>
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user