From 436b52186129e60ba72c20e43d2845bc3f899901 Mon Sep 17 00:00:00 2001
From: Ben Lin <maobin001@msn.com>
Date: 星期四, 22 八月 2024 11:16:56 +0800
Subject: [PATCH] 取消暂停svg更新

---
 src/components/SimpleMenu/src/components/SubMenuItem.vue |  451 ++++++++++++++++++++++++++-----------------------------
 1 files changed, 212 insertions(+), 239 deletions(-)

diff --git a/src/components/SimpleMenu/src/components/SubMenuItem.vue b/src/components/SimpleMenu/src/components/SubMenuItem.vue
index d06e461..9c4a8c6 100644
--- a/src/components/SimpleMenu/src/components/SubMenuItem.vue
+++ b/src/components/SimpleMenu/src/components/SubMenuItem.vue
@@ -10,7 +10,7 @@
         />
       </div>
       <CollapseTransition>
-        <ul :class="prefixCls" v-show="opened">
+        <ul :class="prefixCls" v-show="state.opened">
           <slot></slot>
         </ul>
       </CollapseTransition>
@@ -20,9 +20,10 @@
       placement="right"
       :overlayClassName="`${prefixCls}-menu-popover`"
       v-else
-      :visible="getIsOpend"
-      @visible-change="handleVisibleChange"
+      :open="getIsOpend"
+      @on-open-change="handleVisibleChange"
       :overlayStyle="getOverlayStyle"
+      :overlayInnerStyle="{ padding: 0 }"
       :align="{ offset: [0, 0] }"
     >
       <div :class="getSubClass" v-bind="getEvents(false)">
@@ -44,7 +45,7 @@
         />
       </div>
       <!-- eslint-disable-next-line -->
-      <template #content v-show="opened">
+      <template #content v-show="state.opened">
         <div v-bind="getEvents(true)">
           <ul :class="[prefixCls, `${prefixCls}-${getTheme}`, `${prefixCls}-popup`]">
             <slot></slot>
@@ -55,281 +56,253 @@
   </li>
 </template>
 
-<script lang="ts">
+<script lang="ts" setup>
   import { type TimeoutHandle, type Recordable } from '@vben/types';
   import type { CSSProperties, PropType } from 'vue';
   import type { SubMenuProvider } from './types';
   import {
-    defineComponent,
     computed,
     unref,
     getCurrentInstance,
-    toRefs,
     reactive,
     provide,
     onBeforeMount,
     inject,
   } from 'vue';
-  import { useDesign } from '/@/hooks/web/useDesign';
-  import { propTypes } from '/@/utils/propTypes';
+  import { useDesign } from '@/hooks/web/useDesign';
+  import { propTypes } from '@/utils/propTypes';
   import { useMenuItem } from './useMenu';
   import { useSimpleRootMenuContext } from './useSimpleMenuContext';
-  import { CollapseTransition } from '/@/components/Transition';
+  import { CollapseTransition } from '@/components/Transition';
   import Icon from '@/components/Icon/Icon.vue';
   import { Popover } from 'ant-design-vue';
-  import { isBoolean, isObject } from '/@/utils/is';
-  import { mitt } from '/@/utils/mitt';
+  import { isBoolean, isObject } from '@/utils/is';
+  import { mitt } from '@/utils/mitt';
+
+  defineOptions({ name: 'SubMenu' });
+
+  const props = defineProps({
+    name: {
+      type: [String, Number] as PropType<string | number>,
+      required: true,
+    },
+    disabled: propTypes.bool,
+    collapsedShowTitle: propTypes.bool,
+  });
 
   const DELAY = 200;
-  export default defineComponent({
-    name: 'SubMenu',
-    components: {
-      Icon,
-      CollapseTransition,
-      Popover,
-    },
-    props: {
-      name: {
-        type: [String, Number] as PropType<string | number>,
-        required: true,
+  const instance = getCurrentInstance();
+
+  const state = reactive({
+    active: false,
+    opened: false,
+  });
+
+  const data = reactive({
+    timeout: null as TimeoutHandle | null,
+    mouseInChild: false,
+    isChild: false,
+  });
+
+  const { getParentSubMenu, getItemStyle, getParentMenu, getParentList } = useMenuItem(instance);
+
+  const { prefixCls } = useDesign('menu');
+
+  const subMenuEmitter = mitt();
+
+  const { rootMenuEmitter } = useSimpleRootMenuContext();
+
+  const {
+    addSubMenu: parentAddSubmenu,
+    removeSubMenu: parentRemoveSubmenu,
+    removeAll: parentRemoveAll,
+    getOpenNames: parentGetOpenNames,
+    isRemoveAllPopup,
+    sliceIndex,
+    level,
+    props: rootProps,
+    handleMouseleave: parentHandleMouseleave,
+  } = inject<SubMenuProvider>(`subMenu:${getParentMenu.value?.uid}`)!;
+
+  const getClass = computed(() => {
+    return [
+      `${prefixCls}-submenu`,
+      {
+        [`${prefixCls}-opened`]: state.opened,
+        [`${prefixCls}-submenu-disabled`]: props.disabled,
+        [`${prefixCls}-submenu-has-parent-submenu`]: unref(getParentSubMenu),
+        [`${prefixCls}-child-item-active`]: state.active,
       },
-      disabled: propTypes.bool,
-      collapsedShowTitle: propTypes.bool,
-    },
-    setup(props) {
-      const instance = getCurrentInstance();
+    ];
+  });
 
-      const state = reactive({
-        active: false,
-        opened: false,
+  const getAccordion = computed(() => rootProps.accordion);
+  const getCollapse = computed(() => rootProps.collapse);
+  const getTheme = computed(() => rootProps.theme);
+
+  const getOverlayStyle = computed((): CSSProperties => {
+    return {
+      minWidth: '200px',
+    };
+  });
+
+  const getIsOpend = computed(() => {
+    const name = props.name;
+    if (unref(getCollapse)) {
+      return parentGetOpenNames().includes(name);
+    }
+    return state.opened;
+  });
+
+  const getSubClass = computed(() => {
+    const isActive = rootProps.activeSubMenuNames.includes(props.name);
+    return [
+      `${prefixCls}-submenu-title`,
+      {
+        [`${prefixCls}-submenu-active`]: isActive,
+        [`${prefixCls}-submenu-active-border`]: isActive && level === 0,
+        [`${prefixCls}-submenu-collapse`]: unref(getCollapse) && level === 0,
+      },
+    ];
+  });
+
+  function getEvents(deep: boolean) {
+    if (!unref(getCollapse)) {
+      return {};
+    }
+    return {
+      onMouseenter: handleMouseenter,
+      onMouseleave: () => handleMouseleave(deep),
+    };
+  }
+
+  function handleClick() {
+    const { disabled } = props;
+    if (disabled || unref(getCollapse)) return;
+    const opened = state.opened;
+
+    if (unref(getAccordion)) {
+      const { uidList } = getParentList();
+      rootMenuEmitter.emit('on-update-opened', {
+        opend: false,
+        parent: instance?.parent,
+        uidList: uidList,
       });
-
-      const data = reactive({
-        timeout: null as TimeoutHandle | null,
-        mouseInChild: false,
-        isChild: false,
+    } else {
+      rootMenuEmitter.emit('open-name-change', {
+        name: props.name,
+        opened: !opened,
       });
+    }
+    state.opened = !opened;
+  }
 
-      const { getParentSubMenu, getItemStyle, getParentMenu, getParentList } =
-        useMenuItem(instance);
+  function handleMouseenter() {
+    const disabled = props.disabled;
+    if (disabled) return;
 
-      const { prefixCls } = useDesign('menu');
+    subMenuEmitter.emit('submenu:mouse-enter-child');
 
-      const subMenuEmitter = mitt();
+    const index = parentGetOpenNames().findIndex((item) => item === props.name);
 
-      const { rootMenuEmitter } = useSimpleRootMenuContext();
+    sliceIndex(index);
 
-      const {
-        addSubMenu: parentAddSubmenu,
-        removeSubMenu: parentRemoveSubmenu,
-        removeAll: parentRemoveAll,
-        getOpenNames: parentGetOpenNames,
-        isRemoveAllPopup,
-        sliceIndex,
-        level,
-        props: rootProps,
-        handleMouseleave: parentHandleMouseleave,
-      } = inject<SubMenuProvider>(`subMenu:${getParentMenu.value?.uid}`)!;
+    const isRoot = level === 0 && parentGetOpenNames().length === 2;
+    if (isRoot) {
+      parentRemoveAll();
+    }
+    data.isChild = parentGetOpenNames().includes(props.name);
+    clearTimeout(data.timeout!);
+    data.timeout = setTimeout(() => {
+      parentAddSubmenu(props.name);
+    }, DELAY);
+  }
 
-      const getClass = computed(() => {
-        return [
-          `${prefixCls}-submenu`,
-          {
-            [`${prefixCls}-item-active`]: state.active,
-            [`${prefixCls}-opened`]: state.opened,
-            [`${prefixCls}-submenu-disabled`]: props.disabled,
-            [`${prefixCls}-submenu-has-parent-submenu`]: unref(getParentSubMenu),
-            [`${prefixCls}-child-item-active`]: state.active,
-          },
-        ];
-      });
+  function handleMouseleave(deepDispatch = false) {
+    const parentName = getParentMenu.value?.props.name;
+    if (!parentName) {
+      isRemoveAllPopup.value = true;
+    }
 
-      const getAccordion = computed(() => rootProps.accordion);
-      const getCollapse = computed(() => rootProps.collapse);
-      const getTheme = computed(() => rootProps.theme);
+    if (parentGetOpenNames().slice(-1)[0] === props.name) {
+      data.isChild = false;
+    }
 
-      const getOverlayStyle = computed((): CSSProperties => {
-        return {
-          minWidth: '200px',
-        };
-      });
-
-      const getIsOpend = computed(() => {
-        const name = props.name;
-        if (unref(getCollapse)) {
-          return parentGetOpenNames().includes(name);
-        }
-        return state.opened;
-      });
-
-      const getSubClass = computed(() => {
-        const isActive = rootProps.activeSubMenuNames.includes(props.name);
-        return [
-          `${prefixCls}-submenu-title`,
-          {
-            [`${prefixCls}-submenu-active`]: isActive,
-            [`${prefixCls}-submenu-active-border`]: isActive && level === 0,
-            [`${prefixCls}-submenu-collapse`]: unref(getCollapse) && level === 0,
-          },
-        ];
-      });
-
-      function getEvents(deep: boolean) {
-        if (!unref(getCollapse)) {
-          return {};
-        }
-        return {
-          onMouseenter: handleMouseenter,
-          onMouseleave: () => handleMouseleave(deep),
-        };
-      }
-
-      function handleClick() {
-        const { disabled } = props;
-        if (disabled || unref(getCollapse)) return;
-        const opened = state.opened;
-
-        if (unref(getAccordion)) {
-          const { uidList } = getParentList();
-          rootMenuEmitter.emit('on-update-opened', {
-            opend: false,
-            parent: instance?.parent,
-            uidList: uidList,
-          });
-        } else {
-          rootMenuEmitter.emit('open-name-change', {
-            name: props.name,
-            opened: !opened,
-          });
-        }
-        state.opened = !opened;
-      }
-
-      function handleMouseenter() {
-        const disabled = props.disabled;
-        if (disabled) return;
-
-        subMenuEmitter.emit('submenu:mouse-enter-child');
-
-        const index = parentGetOpenNames().findIndex((item) => item === props.name);
-
-        sliceIndex(index);
-
-        const isRoot = level === 0 && parentGetOpenNames().length === 2;
-        if (isRoot) {
+    subMenuEmitter.emit('submenu:mouse-leave-child');
+    if (data.timeout) {
+      clearTimeout(data.timeout!);
+      data.timeout = setTimeout(() => {
+        if (isRemoveAllPopup.value) {
           parentRemoveAll();
+        } else if (!data.mouseInChild) {
+          parentRemoveSubmenu(props.name);
         }
-        data.isChild = parentGetOpenNames().includes(props.name);
-        clearTimeout(data.timeout!);
-        data.timeout = setTimeout(() => {
-          parentAddSubmenu(props.name);
-        }, DELAY);
+      }, DELAY);
+    }
+    if (deepDispatch) {
+      if (getParentSubMenu.value) {
+        parentHandleMouseleave?.(true);
       }
+    }
+  }
 
-      function handleMouseleave(deepDispatch = false) {
-        const parentName = getParentMenu.value?.props.name;
-        if (!parentName) {
-          isRemoveAllPopup.value = true;
-        }
+  onBeforeMount(() => {
+    subMenuEmitter.on('submenu:mouse-enter-child', () => {
+      data.mouseInChild = true;
+      isRemoveAllPopup.value = false;
+      clearTimeout(data.timeout!);
+    });
+    subMenuEmitter.on('submenu:mouse-leave-child', () => {
+      if (data.isChild) return;
+      data.mouseInChild = false;
+      clearTimeout(data.timeout!);
+    });
 
-        if (parentGetOpenNames().slice(-1)[0] === props.name) {
-          data.isChild = false;
+    rootMenuEmitter.on(
+      'on-update-opened',
+      (data: boolean | (string | number)[] | Recordable<any>) => {
+        if (unref(getCollapse)) return;
+        if (isBoolean(data)) {
+          state.opened = data;
+          return;
         }
-
-        subMenuEmitter.emit('submenu:mouse-leave-child');
-        if (data.timeout) {
-          clearTimeout(data.timeout!);
-          data.timeout = setTimeout(() => {
-            if (isRemoveAllPopup.value) {
-              parentRemoveAll();
-            } else if (!data.mouseInChild) {
-              parentRemoveSubmenu(props.name);
-            }
-          }, DELAY);
-        }
-        if (deepDispatch) {
-          if (getParentSubMenu.value) {
-            parentHandleMouseleave?.(true);
+        if (isObject(data) && rootProps.accordion) {
+          const { opend, parent, uidList } = data as Recordable<any>;
+          if (parent === instance?.parent) {
+            state.opened = opend;
+          } else if (!uidList.includes(instance?.uid)) {
+            state.opened = false;
           }
+          return;
         }
+
+        if (props.name && Array.isArray(data)) {
+          state.opened = (data as (string | number)[]).includes(props.name);
+        }
+      },
+    );
+
+    rootMenuEmitter.on('on-update-active-name:submenu', (data: number[]) => {
+      if (instance?.uid) {
+        state.active = data.includes(instance?.uid);
       }
+    });
+  });
 
-      onBeforeMount(() => {
-        subMenuEmitter.on('submenu:mouse-enter-child', () => {
-          data.mouseInChild = true;
-          isRemoveAllPopup.value = false;
-          clearTimeout(data.timeout!);
-        });
-        subMenuEmitter.on('submenu:mouse-leave-child', () => {
-          if (data.isChild) return;
-          data.mouseInChild = false;
-          clearTimeout(data.timeout!);
-        });
+  function handleVisibleChange(visible: boolean) {
+    state.opened = visible;
+  }
 
-        rootMenuEmitter.on(
-          'on-update-opened',
-          (data: boolean | (string | number)[] | Recordable<any>) => {
-            if (unref(getCollapse)) return;
-            if (isBoolean(data)) {
-              state.opened = data;
-              return;
-            }
-            if (isObject(data) && rootProps.accordion) {
-              const { opend, parent, uidList } = data as Recordable<any>;
-              if (parent === instance?.parent) {
-                state.opened = opend;
-              } else if (!uidList.includes(instance?.uid)) {
-                state.opened = false;
-              }
-              return;
-            }
-
-            if (props.name && Array.isArray(data)) {
-              state.opened = (data as (string | number)[]).includes(props.name);
-            }
-          },
-        );
-
-        rootMenuEmitter.on('on-update-active-name:submenu', (data: number[]) => {
-          if (instance?.uid) {
-            state.active = data.includes(instance?.uid);
-          }
-        });
-      });
-
-      function handleVisibleChange(visible: boolean) {
-        state.opened = visible;
-      }
-
-      // provide
-      provide<SubMenuProvider>(`subMenu:${instance?.uid}`, {
-        addSubMenu: parentAddSubmenu,
-        removeSubMenu: parentRemoveSubmenu,
-        getOpenNames: parentGetOpenNames,
-        removeAll: parentRemoveAll,
-        isRemoveAllPopup,
-        sliceIndex,
-        level: level + 1,
-        handleMouseleave,
-        props: rootProps,
-      });
-
-      return {
-        getClass,
-        prefixCls,
-        getCollapse,
-        getItemStyle,
-        handleClick,
-        handleVisibleChange,
-        getParentSubMenu,
-        getOverlayStyle,
-        getTheme,
-        getIsOpend,
-        getEvents,
-        getSubClass,
-        ...toRefs(state),
-        ...toRefs(data),
-      };
-    },
+  // provide
+  provide<SubMenuProvider>(`subMenu:${instance?.uid}`, {
+    addSubMenu: parentAddSubmenu,
+    removeSubMenu: parentRemoveSubmenu,
+    getOpenNames: parentGetOpenNames,
+    removeAll: parentRemoveAll,
+    isRemoveAllPopup,
+    sliceIndex,
+    level: level + 1,
+    handleMouseleave,
+    props: rootProps,
   });
 </script>

--
Gitblit v1.9.3