mirror of
				https://github.com/pure-admin/vue-pure-admin.git
				synced 2025-11-03 13:44:47 +08:00 
			
		
		
		
	perf: layout style
This commit is contained in:
		
							parent
							
								
									73705eb0e4
								
							
						
					
					
						commit
						0eb0b7395e
					
				@ -29,10 +29,21 @@ const transitions = computed(() => {
 | 
			
		||||
const hideTabs = computed(() => {
 | 
			
		||||
  return instance?.sets.hideTabs;
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const layout = computed(() => {
 | 
			
		||||
  return instance?.layout.layout === "vertical";
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const getSectionStyle = computed(() => {
 | 
			
		||||
  return [
 | 
			
		||||
    hideTabs.value && layout ? "padding-top: 48px;" : "",
 | 
			
		||||
    !hideTabs.value && layout ? "padding-top: 85px;" : "",
 | 
			
		||||
    hideTabs.value && !layout.value ? "padding-top: 48px" : "",
 | 
			
		||||
    !hideTabs.value && !layout.value ? "padding-top: 85px;" : "",
 | 
			
		||||
    props.fixedHeader ? "" : "padding-top: 0;"
 | 
			
		||||
  ];
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const transitionMain = defineComponent({
 | 
			
		||||
  render() {
 | 
			
		||||
    return h(
 | 
			
		||||
@ -71,12 +82,7 @@ const transitionMain = defineComponent({
 | 
			
		||||
<template>
 | 
			
		||||
  <section
 | 
			
		||||
    :class="[props.fixedHeader ? 'app-main' : 'app-main-nofixed-header']"
 | 
			
		||||
    :style="[
 | 
			
		||||
      hideTabs && layout ? 'padding-top: 48px;' : '',
 | 
			
		||||
      !hideTabs && layout ? 'padding-top: 85px;' : '',
 | 
			
		||||
      hideTabs && !layout ? 'padding-top: 48px' : '',
 | 
			
		||||
      !hideTabs && !layout ? 'padding-top: 85px;' : ''
 | 
			
		||||
    ]"
 | 
			
		||||
    :style="getSectionStyle"
 | 
			
		||||
  >
 | 
			
		||||
    <router-view>
 | 
			
		||||
      <template #default="{ Component, route }">
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,5 @@
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { computed } from "vue";
 | 
			
		||||
import { useI18n } from "vue-i18n";
 | 
			
		||||
import { emitter } from "/@/utils/mitt";
 | 
			
		||||
import Notice from "./notice/index.vue";
 | 
			
		||||
@ -22,6 +23,15 @@ const route = useRoute();
 | 
			
		||||
let usename = storageSession.getItem("info")?.username;
 | 
			
		||||
const { locale } = useI18n();
 | 
			
		||||
 | 
			
		||||
const getDropdownItemStyle = computed(() => {
 | 
			
		||||
  return t => {
 | 
			
		||||
    return {
 | 
			
		||||
      background: locale.value === t ? "#1b2a47" : "",
 | 
			
		||||
      color: locale.value === t ? "#f4f4f5" : "#000"
 | 
			
		||||
    };
 | 
			
		||||
  };
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
watch(
 | 
			
		||||
  () => locale.value,
 | 
			
		||||
  () => {
 | 
			
		||||
@ -82,20 +92,14 @@ function translationEn() {
 | 
			
		||||
        <template #dropdown>
 | 
			
		||||
          <el-dropdown-menu class="translation">
 | 
			
		||||
            <el-dropdown-item
 | 
			
		||||
              :style="{
 | 
			
		||||
                background: locale === 'zh' ? '#1b2a47' : '',
 | 
			
		||||
                color: locale === 'zh' ? '#f4f4f5' : '#000'
 | 
			
		||||
              }"
 | 
			
		||||
              :style="getDropdownItemStyle('zh')"
 | 
			
		||||
              @click="translationCh"
 | 
			
		||||
              ><el-icon class="check-zh" v-show="locale === 'zh'"
 | 
			
		||||
                ><check /></el-icon
 | 
			
		||||
              >简体中文</el-dropdown-item
 | 
			
		||||
            >
 | 
			
		||||
            <el-dropdown-item
 | 
			
		||||
              :style="{
 | 
			
		||||
                background: locale === 'en' ? '#1b2a47' : '',
 | 
			
		||||
                color: locale === 'en' ? '#f4f4f5' : '#000'
 | 
			
		||||
              }"
 | 
			
		||||
              :style="getDropdownItemStyle('en')"
 | 
			
		||||
              @click="translationEn"
 | 
			
		||||
              ><el-icon class="check-en" v-show="locale === 'en'"
 | 
			
		||||
                ><check /></el-icon
 | 
			
		||||
 | 
			
		||||
@ -11,9 +11,9 @@ import {
 | 
			
		||||
} from "vue";
 | 
			
		||||
import rgbHex from "rgb-hex";
 | 
			
		||||
import { find } from "lodash-es";
 | 
			
		||||
import panel from "../panel/index.vue";
 | 
			
		||||
import { getConfig } from "/@/config";
 | 
			
		||||
import { useRouter } from "vue-router";
 | 
			
		||||
import panel from "../panel/index.vue";
 | 
			
		||||
import { emitter } from "/@/utils/mitt";
 | 
			
		||||
import { templateRef } from "@vueuse/core";
 | 
			
		||||
import dayIcon from "/@/assets/svg/day.svg";
 | 
			
		||||
@ -92,6 +92,12 @@ const settings = reactive({
 | 
			
		||||
  multiTagsCache: instance.sets.multiTagsCache
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const getThemeColorStyle = computed(() => {
 | 
			
		||||
  return rgb => {
 | 
			
		||||
    return { background: `rgb(${rgb})` };
 | 
			
		||||
  };
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
function toggleClass(flag: boolean, clsName: string, target?: HTMLElement) {
 | 
			
		||||
  const targetEl = target || document.body;
 | 
			
		||||
  let { className } = targetEl;
 | 
			
		||||
@ -338,7 +344,7 @@ nextTick(() => {
 | 
			
		||||
      <li
 | 
			
		||||
        v-for="(item, index) in themeColors"
 | 
			
		||||
        :key="index"
 | 
			
		||||
        :style="{ background: `rgb(${item.rgb})` }"
 | 
			
		||||
        :style="getThemeColorStyle(item.rgb)"
 | 
			
		||||
        @click="setLayoutThemeColor(item.themeColor)"
 | 
			
		||||
      >
 | 
			
		||||
        <el-icon
 | 
			
		||||
 | 
			
		||||
@ -35,6 +35,15 @@ const routers = useRouter().options.routes;
 | 
			
		||||
let usename = storageSession.getItem("info")?.username;
 | 
			
		||||
const { locale, t } = useI18n();
 | 
			
		||||
 | 
			
		||||
const getDropdownItemStyle = computed(() => {
 | 
			
		||||
  return t => {
 | 
			
		||||
    return {
 | 
			
		||||
      background: locale.value === t ? "#1b2a47" : "",
 | 
			
		||||
      color: locale.value === t ? "#f4f4f5" : "#000"
 | 
			
		||||
    };
 | 
			
		||||
  };
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
watch(
 | 
			
		||||
  () => locale.value,
 | 
			
		||||
  () => {
 | 
			
		||||
@ -149,20 +158,14 @@ onMounted(() => {
 | 
			
		||||
        <template #dropdown>
 | 
			
		||||
          <el-dropdown-menu class="translation">
 | 
			
		||||
            <el-dropdown-item
 | 
			
		||||
              :style="{
 | 
			
		||||
                background: locale === 'zh' ? '#1b2a47' : '',
 | 
			
		||||
                color: locale === 'zh' ? '#f4f4f5' : '#000'
 | 
			
		||||
              }"
 | 
			
		||||
              :style="getDropdownItemStyle('zh')"
 | 
			
		||||
              @click="translationCh"
 | 
			
		||||
              ><el-icon class="check-zh" v-show="locale === 'zh'"
 | 
			
		||||
                ><check /></el-icon
 | 
			
		||||
              >简体中文</el-dropdown-item
 | 
			
		||||
            >
 | 
			
		||||
            <el-dropdown-item
 | 
			
		||||
              :style="{
 | 
			
		||||
                background: locale === 'en' ? '#1b2a47' : '',
 | 
			
		||||
                color: locale === 'en' ? '#f4f4f5' : '#000'
 | 
			
		||||
              }"
 | 
			
		||||
              :style="getDropdownItemStyle('en')"
 | 
			
		||||
              @click="translationEn"
 | 
			
		||||
              ><el-icon class="check-en" v-show="locale === 'en'"
 | 
			
		||||
                ><check /></el-icon
 | 
			
		||||
 | 
			
		||||
@ -1,11 +1,19 @@
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import {
 | 
			
		||||
  ref,
 | 
			
		||||
  PropType,
 | 
			
		||||
  nextTick,
 | 
			
		||||
  computed,
 | 
			
		||||
  CSSProperties,
 | 
			
		||||
  getCurrentInstance
 | 
			
		||||
} from "vue";
 | 
			
		||||
import path from "path";
 | 
			
		||||
import { PropType, ref, nextTick, getCurrentInstance } from "vue";
 | 
			
		||||
import { childrenType } from "../../types";
 | 
			
		||||
import { useAppStoreHook } from "/@/store/modules/app";
 | 
			
		||||
import Icon from "/@/components/ReIcon/src/Icon.vue";
 | 
			
		||||
import { transformI18n } from "/@/plugins/i18n";
 | 
			
		||||
import { findIconReg } from "/@/components/ReIcon";
 | 
			
		||||
import Icon from "/@/components/ReIcon/src/Icon.vue";
 | 
			
		||||
import { useAppStoreHook } from "/@/store/modules/app";
 | 
			
		||||
 | 
			
		||||
const instance = getCurrentInstance().appContext.app.config.globalProperties;
 | 
			
		||||
const menuMode = instance.$storage.layout?.layout === "vertical";
 | 
			
		||||
const pureApp = useAppStoreHook();
 | 
			
		||||
@ -24,6 +32,48 @@ const props = defineProps({
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const getNoDropdownStyle = computed((): CSSProperties => {
 | 
			
		||||
  return {
 | 
			
		||||
    display: "flex",
 | 
			
		||||
    alignItems: "center"
 | 
			
		||||
  };
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const getDivStyle = computed((): CSSProperties => {
 | 
			
		||||
  return {
 | 
			
		||||
    width: pureApp.sidebar.opened ? "" : "100%",
 | 
			
		||||
    display: "flex",
 | 
			
		||||
    alignItems: "center",
 | 
			
		||||
    justifyContent: "space-between",
 | 
			
		||||
    overflow: "hidden"
 | 
			
		||||
  };
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const getMenuTextStyle = computed((): CSSProperties => {
 | 
			
		||||
  return {
 | 
			
		||||
    width: pureApp.sidebar.opened ? "125px" : "",
 | 
			
		||||
    overflow: "hidden",
 | 
			
		||||
    textOverflow: "ellipsis",
 | 
			
		||||
    outline: "none"
 | 
			
		||||
  };
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const getSubTextStyle = computed((): CSSProperties => {
 | 
			
		||||
  return {
 | 
			
		||||
    width: pureApp.sidebar.opened ? "125px" : "",
 | 
			
		||||
    display: "inline-block",
 | 
			
		||||
    overflow: "hidden",
 | 
			
		||||
    textOverflow: "ellipsis"
 | 
			
		||||
  };
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const getSpanStyle = computed((): CSSProperties => {
 | 
			
		||||
  return {
 | 
			
		||||
    overflow: "hidden",
 | 
			
		||||
    textOverflow: "ellipsis"
 | 
			
		||||
  };
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const onlyOneChild: childrenType = ref(null);
 | 
			
		||||
// 存放菜单是否存在showTooltip属性标识
 | 
			
		||||
const hoverMenuMap = new WeakMap();
 | 
			
		||||
@ -88,7 +138,7 @@ function resolvePath(routePath) {
 | 
			
		||||
    <el-menu-item
 | 
			
		||||
      :index="resolvePath(onlyOneChild.path)"
 | 
			
		||||
      :class="{ 'submenu-title-noDropdown': !isNest }"
 | 
			
		||||
      style="display: flex; align-items: center"
 | 
			
		||||
      :style="getNoDropdownStyle"
 | 
			
		||||
    >
 | 
			
		||||
      <el-icon v-show="props.item.meta.icon">
 | 
			
		||||
        <component
 | 
			
		||||
@ -101,15 +151,7 @@ function resolvePath(routePath) {
 | 
			
		||||
        ></component>
 | 
			
		||||
      </el-icon>
 | 
			
		||||
      <template #title>
 | 
			
		||||
        <div
 | 
			
		||||
          :style="{
 | 
			
		||||
            width: pureApp.sidebar.opened ? '' : '100%',
 | 
			
		||||
            display: 'flex',
 | 
			
		||||
            alignItems: 'center',
 | 
			
		||||
            justifyContent: 'space-between',
 | 
			
		||||
            overflow: 'hidden'
 | 
			
		||||
          }"
 | 
			
		||||
        >
 | 
			
		||||
        <div :style="getDivStyle">
 | 
			
		||||
          <span v-if="!menuMode">{{
 | 
			
		||||
            transformI18n(onlyOneChild.meta.title, onlyOneChild.meta.i18n)
 | 
			
		||||
          }}</span>
 | 
			
		||||
@ -126,12 +168,7 @@ function resolvePath(routePath) {
 | 
			
		||||
            </template>
 | 
			
		||||
            <span
 | 
			
		||||
              ref="menuTextRef"
 | 
			
		||||
              :style="{
 | 
			
		||||
                width: pureApp.sidebar.opened ? '125px' : '',
 | 
			
		||||
                overflow: 'hidden',
 | 
			
		||||
                textOverflow: 'ellipsis',
 | 
			
		||||
                outline: 'none'
 | 
			
		||||
              }"
 | 
			
		||||
              :style="getMenuTextStyle"
 | 
			
		||||
              @mouseover="hoverMenu(onlyOneChild)"
 | 
			
		||||
            >
 | 
			
		||||
              {{
 | 
			
		||||
@ -175,15 +212,10 @@ function resolvePath(routePath) {
 | 
			
		||||
        </template>
 | 
			
		||||
        <div
 | 
			
		||||
          ref="menuTextRef"
 | 
			
		||||
          :style="{
 | 
			
		||||
            width: pureApp.sidebar.opened ? '125px' : '',
 | 
			
		||||
            display: 'inline-block',
 | 
			
		||||
            overflow: 'hidden',
 | 
			
		||||
            textOverflow: 'ellipsis'
 | 
			
		||||
          }"
 | 
			
		||||
          :style="getSubTextStyle"
 | 
			
		||||
          @mouseover="hoverMenu(props.item)"
 | 
			
		||||
        >
 | 
			
		||||
          <span style="overflow: hidden; text-overflow: ellipsis">
 | 
			
		||||
          <span :style="getSpanStyle">
 | 
			
		||||
            {{ transformI18n(props.item.meta.title, props.item.meta.i18n) }}
 | 
			
		||||
          </span>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
@ -2,12 +2,13 @@
 | 
			
		||||
import {
 | 
			
		||||
  ref,
 | 
			
		||||
  watch,
 | 
			
		||||
  onBeforeMount,
 | 
			
		||||
  unref,
 | 
			
		||||
  nextTick,
 | 
			
		||||
  computed,
 | 
			
		||||
  getCurrentInstance,
 | 
			
		||||
  ComputedRef
 | 
			
		||||
  ComputedRef,
 | 
			
		||||
  CSSProperties,
 | 
			
		||||
  onBeforeMount,
 | 
			
		||||
  getCurrentInstance
 | 
			
		||||
} from "vue";
 | 
			
		||||
 | 
			
		||||
import close from "/@/assets/svg/close.svg";
 | 
			
		||||
@ -610,17 +611,23 @@ onBeforeMount(() => {
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const getTabStyle = computed((): CSSProperties => {
 | 
			
		||||
  return {
 | 
			
		||||
    transform: `translateX(${translateX.value}px)`
 | 
			
		||||
  };
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const getContextMenuStyle = computed((): CSSProperties => {
 | 
			
		||||
  return { left: buttonLeft.value + "px", top: buttonTop.value + "px" };
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
  <div ref="containerDom" class="tags-view" v-if="!showTags">
 | 
			
		||||
    <i class="ri-arrow-left-s-line" @click="handleScroll(200)"></i>
 | 
			
		||||
    <div ref="scrollbarDom" class="scroll-container">
 | 
			
		||||
      <div
 | 
			
		||||
        class="tab"
 | 
			
		||||
        ref="tabDom"
 | 
			
		||||
        :style="{ transform: `translateX(${translateX}px)` }"
 | 
			
		||||
      >
 | 
			
		||||
      <div class="tab" ref="tabDom" :style="getTabStyle">
 | 
			
		||||
        <div
 | 
			
		||||
          :ref="'dynamic' + index"
 | 
			
		||||
          v-for="(item, index) in multiTags"
 | 
			
		||||
@ -664,7 +671,7 @@ onBeforeMount(() => {
 | 
			
		||||
      <ul
 | 
			
		||||
        v-show="visible"
 | 
			
		||||
        :key="Math.random()"
 | 
			
		||||
        :style="{ left: buttonLeft + 'px', top: buttonTop + 'px' }"
 | 
			
		||||
        :style="getContextMenuStyle"
 | 
			
		||||
        class="contextmenu"
 | 
			
		||||
      >
 | 
			
		||||
        <div
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user