瀏覽代碼

feat: 添加 `TooltipEffect` 全局配置,可配置平台主体所有 `el-tooltip` 的 `effect`,不影响业务代码

xiaoxian521 2 年之前
父節點
當前提交
86b77c2877

+ 1 - 1
package.json

@@ -48,7 +48,7 @@
     "dayjs": "^1.11.6",
     "echarts": "^5.4.0",
     "el-table-infinite-scroll": "^3.0.1",
-    "element-plus": "^2.2.25",
+    "element-plus": "^2.2.26",
     "element-resize-detector": "^1.2.4",
     "intro.js": "^6.0.0",
     "js-cookie": "^3.0.1",

+ 11 - 11
pnpm-lock.yaml

@@ -48,7 +48,7 @@ specifiers:
   dayjs: ^1.11.6
   echarts: ^5.4.0
   el-table-infinite-scroll: ^3.0.1
-  element-plus: ^2.2.25
+  element-plus: ^2.2.26
   element-resize-detector: ^1.2.4
   eslint: ^8.8.0
   eslint-plugin-prettier: ^4.0.0
@@ -125,8 +125,8 @@ dependencies:
   "@howdyjs/mouse-menu": 2.0.5_vue@3.2.45
   "@logicflow/core": 1.1.31
   "@logicflow/extension": 1.1.31
-  "@pureadmin/descriptions": 1.1.1_element-plus@2.2.25
-  "@pureadmin/table": 1.8.1_element-plus@2.2.25
+  "@pureadmin/descriptions": 1.1.1_element-plus@2.2.26
+  "@pureadmin/table": 1.8.1_element-plus@2.2.26
   "@pureadmin/utils": 1.7.1_aotapuqn7htzdjltsyimavekky
   "@vueuse/core": 9.6.0_vue@3.2.45
   "@vueuse/motion": 2.0.0-beta.12_vue@3.2.45
@@ -139,7 +139,7 @@ dependencies:
   dayjs: 1.11.6
   echarts: 5.4.0
   el-table-infinite-scroll: 3.0.1
-  element-plus: 2.2.25_vue@3.2.45
+  element-plus: 2.2.26_vue@3.2.45
   element-resize-detector: 1.2.4
   intro.js: 6.0.0
   js-cookie: 3.0.1
@@ -1264,7 +1264,7 @@ packages:
       fastq: 1.13.0
     dev: true
 
-  /@pureadmin/descriptions/1.1.1_element-plus@2.2.25:
+  /@pureadmin/descriptions/1.1.1_element-plus@2.2.26:
     resolution:
       {
         integrity: sha512-4BHLKomLU/LxGs5EUA+h+aKNrJEkhrU6+QE8VoWfJZ8VTU6ddvFLT/Pi4WuO5CWNXM9ZjqvHLFFVwEPlKntqtg==
@@ -1273,11 +1273,11 @@ packages:
       element-plus: ^2.0.0
     dependencies:
       "@element-plus/icons-vue": 2.0.10_vue@3.2.45
-      element-plus: 2.2.25_vue@3.2.45
+      element-plus: 2.2.26_vue@3.2.45
       vue: 3.2.45
     dev: false
 
-  /@pureadmin/table/1.8.1_element-plus@2.2.25:
+  /@pureadmin/table/1.8.1_element-plus@2.2.26:
     resolution:
       {
         integrity: sha512-oZ5GYmLTDgQ64U6+yKFjvpZG2Seuudk3hOWnUogMvKxhIvaRQsGBHbvyg47asMmXxUyeilq+nRumyuiuV7WJTg==
@@ -1285,7 +1285,7 @@ packages:
     peerDependencies:
       element-plus: ^2.0.0
     dependencies:
-      element-plus: 2.2.25_vue@3.2.45
+      element-plus: 2.2.26_vue@3.2.45
       vue: 3.2.45
     dev: false
 
@@ -3758,7 +3758,7 @@ packages:
       }
     dependencies:
       core-js: 3.26.1
-      element-plus: 2.2.25_vue@3.2.45
+      element-plus: 2.2.26_vue@3.2.45
       vue: 3.2.45
     transitivePeerDependencies:
       - "@vue/composition-api"
@@ -3771,10 +3771,10 @@ packages:
       }
     dev: true
 
-  /element-plus/2.2.25_vue@3.2.45:
+  /element-plus/2.2.26_vue@3.2.45:
     resolution:
       {
-        integrity: sha512-HC8CWY31e6pPyBpgqI0QnWkBgs0vRzdYnEw3mpdM/NlKfp0PtNFX7NESQLomqoIulH5ftL09hjQmJNvZBQpthQ==
+        integrity: sha512-O/rdY5m9DkclpVg8r3GynyqCunm7MxSR142xSsjrZA77bi7bcwA3SIy6SPEDqHi5R4KqgkGYgKSp4Q4e3irbYg==
       }
     peerDependencies:
       vue: ^3.2.0

+ 1 - 0
public/serverConfig.json

@@ -18,6 +18,7 @@
   "ShowModel": "smart",
   "MenuArrowIconNoTransition": true,
   "CachingAsyncRoutes": true,
+  "TooltipEffect": "light",
   "MapConfigure": {
     "amapKey": "97b3248d1553172e81f168cf94ea667e",
     "options": {

+ 4 - 0
src/layout/components/notice/noticeItem.vue

@@ -1,6 +1,7 @@
 <script setup lang="ts">
 import { ListItem } from "./data";
 import { ref, PropType, nextTick } from "vue";
+import { useNav } from "@/layout/hooks/useNav";
 
 const props = defineProps({
   noticeItem: {
@@ -13,6 +14,7 @@ const titleRef = ref(null);
 const titleTooltip = ref(false);
 const descriptionRef = ref(null);
 const descriptionTooltip = ref(false);
+const { tooltipEffect } = useNav();
 
 function hoverTitle() {
   nextTick(() => {
@@ -57,6 +59,7 @@ function hoverDescription(event, description) {
       <div class="notice-text-title text-[#000000d9] dark:text-white">
         <el-tooltip
           popper-class="notice-title-popper"
+          :effect="tooltipEffect"
           :disabled="!titleTooltip"
           :content="props.noticeItem.title"
           placement="top-start"
@@ -81,6 +84,7 @@ function hoverDescription(event, description) {
 
       <el-tooltip
         popper-class="notice-title-popper"
+        :effect="tooltipEffect"
         :disabled="!descriptionTooltip"
         :content="props.noticeItem.description"
         placement="top-start"

+ 51 - 52
src/layout/components/setting/index.vue

@@ -1,13 +1,11 @@
 <script setup lang="ts">
 import {
-  ref,
-  unref,
-  watch,
-  reactive,
-  computed,
-  nextTick,
-  useCssModule
-} from "vue";
+  useDark,
+  debounce,
+  useGlobal,
+  storageLocal,
+  storageSession
+} from "@pureadmin/utils";
 import { getConfig } from "@/config";
 import { useRouter } from "vue-router";
 import panel from "../panel/index.vue";
@@ -17,16 +15,10 @@ import { removeToken } from "@/utils/auth";
 import { routerArrays } from "@/layout/types";
 import { useNav } from "@/layout/hooks/useNav";
 import { useAppStoreHook } from "@/store/modules/app";
+import { toggleTheme } from "@pureadmin/theme/dist/browser-utils";
 import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
+import { ref, unref, watch, reactive, computed, nextTick } from "vue";
 import { useDataThemeChange } from "@/layout/hooks/useDataThemeChange";
-import {
-  useDark,
-  debounce,
-  useGlobal,
-  storageLocal,
-  storageSession
-} from "@pureadmin/utils";
-import { toggleTheme } from "@pureadmin/theme/dist/browser-utils";
 
 import dayIcon from "@/assets/svg/day.svg?component";
 import darkIcon from "@/assets/svg/dark.svg?component";
@@ -34,9 +26,8 @@ import Check from "@iconify-icons/ep/check";
 import Logout from "@iconify-icons/ri/logout-circle-r-line";
 
 const router = useRouter();
-const { device } = useNav();
 const { isDark } = useDark();
-const { isSelect } = useCssModule();
+const { device, tooltipEffect } = useNav();
 const { $storage } = useGlobal<GlobalPropertiesApi>();
 
 const mixRef = ref();
@@ -161,30 +152,10 @@ function logoChange() {
 
 function setFalse(Doms): any {
   Doms.forEach(v => {
-    toggleClass(false, isSelect, unref(v));
+    toggleClass(false, "is-select", unref(v));
   });
 }
 
-watch($storage, ({ layout }) => {
-  switch (layout["layout"]) {
-    case "vertical":
-      toggleClass(true, isSelect, unref(verticalRef));
-      debounce(setFalse([horizontalRef]), 50);
-      debounce(setFalse([mixRef]), 50);
-      break;
-    case "horizontal":
-      toggleClass(true, isSelect, unref(horizontalRef));
-      debounce(setFalse([verticalRef]), 50);
-      debounce(setFalse([mixRef]), 50);
-      break;
-    case "mix":
-      toggleClass(true, isSelect, unref(mixRef));
-      debounce(setFalse([verticalRef]), 50);
-      debounce(setFalse([horizontalRef]), 50);
-      break;
-  }
-});
-
 /** 主题色 激活选择项 */
 const getThemeColor = computed(() => {
   return current => {
@@ -227,6 +198,26 @@ nextTick(() => {
   settings.tabsVal && tagsChange();
   dataThemeChange();
 });
+
+watch($storage, ({ layout }) => {
+  switch (layout["layout"]) {
+    case "vertical":
+      toggleClass(true, "is-select", unref(verticalRef));
+      debounce(setFalse([horizontalRef]), 50);
+      debounce(setFalse([mixRef]), 50);
+      break;
+    case "horizontal":
+      toggleClass(true, "is-select", unref(horizontalRef));
+      debounce(setFalse([verticalRef]), 50);
+      debounce(setFalse([mixRef]), 50);
+      break;
+    case "mix":
+      toggleClass(true, "is-select", unref(mixRef));
+      debounce(setFalse([verticalRef]), 50);
+      debounce(setFalse([horizontalRef]), 50);
+      break;
+  }
+});
 </script>
 
 <template>
@@ -243,9 +234,15 @@ nextTick(() => {
 
     <el-divider>导航栏模式</el-divider>
     <ul class="pure-theme">
-      <el-tooltip class="item" content="左侧模式" placement="bottom">
+      <el-tooltip
+        :effect="tooltipEffect"
+        class="item"
+        content="左侧模式"
+        placement="bottom"
+        popper-class="pure-tooltip"
+      >
         <li
-          :class="layoutTheme.layout === 'vertical' ? $style.isSelect : ''"
+          :class="layoutTheme.layout === 'vertical' ? 'is-select' : ''"
           ref="verticalRef"
           @click="setLayoutModel('vertical')"
         >
@@ -256,12 +253,14 @@ nextTick(() => {
 
       <el-tooltip
         v-if="device !== 'mobile'"
+        :effect="tooltipEffect"
         class="item"
         content="顶部模式"
         placement="bottom"
+        popper-class="pure-tooltip"
       >
         <li
-          :class="layoutTheme.layout === 'horizontal' ? $style.isSelect : ''"
+          :class="layoutTheme.layout === 'horizontal' ? 'is-select' : ''"
           ref="horizontalRef"
           @click="setLayoutModel('horizontal')"
         >
@@ -272,12 +271,14 @@ nextTick(() => {
 
       <el-tooltip
         v-if="device !== 'mobile'"
+        :effect="tooltipEffect"
         class="item"
         content="混合模式"
         placement="bottom"
+        popper-class="pure-tooltip"
       >
         <li
-          :class="layoutTheme.layout === 'mix' ? $style.isSelect : ''"
+          :class="layoutTheme.layout === 'mix' ? 'is-select' : ''"
           ref="mixRef"
           @click="setLayoutModel('mix')"
         >
@@ -392,13 +393,16 @@ nextTick(() => {
   </panel>
 </template>
 
-<style scoped module>
-.isSelect {
+<style lang="scss" scoped>
+:deep(.el-divider__text) {
+  font-size: 16px;
+  font-weight: 700;
+}
+
+.is-select {
   border: 2px solid var(--el-color-primary);
 }
-</style>
 
-<style lang="scss" scoped>
 .setting {
   width: 100%;
 
@@ -410,11 +414,6 @@ nextTick(() => {
   }
 }
 
-:deep(.el-divider__text) {
-  font-size: 16px;
-  font-weight: 700;
-}
-
 .pure-datatheme {
   width: 100%;
   height: 50px;

+ 3 - 3
src/layout/components/sidebar/leftCollapse.vue

@@ -1,5 +1,5 @@
 <script setup lang="ts">
-import { useDark } from "@pureadmin/utils";
+import { useNav } from "@/layout/hooks/useNav";
 import MenuFold from "@iconify-icons/ri/menu-fold-fill";
 import MenuUnfold from "@iconify-icons/ri/menu-unfold-fill";
 
@@ -10,7 +10,7 @@ interface Props {
 const props = withDefaults(defineProps<Props>(), {
   isActive: false
 });
-const { isDark } = useDark();
+const { tooltipEffect } = useNav();
 
 const emit = defineEmits<{
   (e: "toggleClick"): void;
@@ -25,7 +25,7 @@ const toggleClick = () => {
   <div class="container">
     <el-tooltip
       placement="right"
-      :effect="isDark ? 'dark' : 'light'"
+      :effect="tooltipEffect"
       :content="props.isActive ? '点击折叠' : '点击展开'"
     >
       <IconifyIconOffline

+ 3 - 1
src/layout/components/sidebar/sidebarItem.vue

@@ -12,7 +12,7 @@ import EpArrowDown from "@iconify-icons/ep/arrow-down";
 import ArrowLeft from "@iconify-icons/ep/arrow-left";
 import ArrowRight from "@iconify-icons/ep/arrow-right";
 
-const { layout, isCollapse } = useNav();
+const { layout, isCollapse, tooltipEffect } = useNav();
 
 const props = defineProps({
   item: {
@@ -201,6 +201,7 @@ function resolvePath(routePath) {
           <el-tooltip
             v-else
             placement="top"
+            :effect="tooltipEffect"
             :offset="-10"
             :disabled="!onlyOneChild.showTooltip"
           >
@@ -246,6 +247,7 @@ function resolvePath(routePath) {
       <el-tooltip
         v-else
         placement="top"
+        :effect="tooltipEffect"
         :offset="-10"
         :disabled="!isCollapse || !props.item.showTooltip"
       >

+ 10 - 2
src/layout/components/sidebar/vertical.vue

@@ -15,8 +15,15 @@ const showLogo = ref(
   storageLocal.getItem<StorageConfigs>("responsive-configure")?.showLogo ?? true
 );
 
-const { routers, device, pureApp, isCollapse, menuSelect, toggleSideBar } =
-  useNav();
+const {
+  routers,
+  device,
+  pureApp,
+  isCollapse,
+  tooltipEffect,
+  menuSelect,
+  toggleSideBar
+} = useNav();
 
 const subMenuData = ref([]);
 
@@ -69,6 +76,7 @@ watch(
         router
         unique-opened
         mode="vertical"
+        :popper-effect="tooltipEffect"
         class="outer-most select-none"
         :collapse="isCollapse"
         :default-active="route.path"

+ 3 - 0
src/layout/hooks/useNav.ts

@@ -18,6 +18,8 @@ export function useNav() {
   const pureApp = useAppStoreHook();
   const routers = useRouter().options.routes;
   const { wholeMenus } = storeToRefs(usePermissionStoreHook());
+  /** 平台`layout`中所有`el-tooltip`的`effect`配置,默认`light` */
+  const tooltipEffect = getConfig()?.TooltipEffect ?? "light";
 
   /** 用户名 */
   const username = computed(() => {
@@ -153,6 +155,7 @@ export function useNav() {
     pureApp,
     username,
     avatarsStyle,
+    tooltipEffect,
     getDropdownItemStyle,
     getDropdownItemClass
   };

+ 6 - 0
src/style/element-plus.scss

@@ -46,6 +46,12 @@
   padding: 0 !important;
 }
 
+/* 自定义 tooltip 的类名 */
+.pure-tooltip {
+  // 右侧操作面板right-panel类名的z-index为40000,tooltip需要大于它才能显示
+  z-index: 41000 !important;
+}
+
 /* nprogress 适配 element-plus 的主题色 */
 #nprogress {
   & .bar {

+ 1 - 2
types/global.d.ts

@@ -4,9 +4,7 @@ import type {
   PropType as VuePropType,
   ComponentPublicInstance
 } from "vue";
-import type { ECharts } from "echarts";
 import type { IconifyIcon } from "@iconify/vue";
-import type { ResponsiveStorage } from "./index";
 import type { TableColumns } from "@pureadmin/table";
 import { type RouteComponent, type RouteLocationNormalized } from "vue-router";
 
@@ -96,6 +94,7 @@ declare global {
     ShowModel?: string;
     MenuArrowIconNoTransition?: boolean;
     CachingAsyncRoutes?: boolean;
+    TooltipEffect?: Effect;
     MapConfigure?: {
       amapKey?: string;
       options: {

+ 2 - 0
types/index.d.ts

@@ -45,6 +45,8 @@ type TimeoutHandle = ReturnType<typeof setTimeout>;
 
 type IntervalHandle = ReturnType<typeof setInterval>;
 
+type Effect = "light" | "dark";
+
 interface ChangeEvent extends Event {
   target: HTMLInputElement;
 }