Prechádzať zdrojové kódy

fix: 优化颜色列表卡顿问题

mtruning 3 rokov pred
rodič
commit
109a1a8d7a

+ 89 - 77
src/components/ThemeColorSelect/components/ColorList.vue

@@ -1,101 +1,113 @@
 <template>
-  <div
-    class="content-left-item go-transition-quick go-mb-0"
-    span="12 1000:6 1400:4 1800:4 2200:2"
-    v-for="(item, index) in designColorRecommend"
-    :key="index"
-    @click="colorSelectHandle(item)"
-  >
-    <n-space>
-      <div class="content-left-item-color" :style="{ backgroundColor: item.hex }" />
-      <n-space vertical>
-        <n-space>
-          <span :style="{ color: item.hex }">{{ item.name }}</span>
-          <span class="Pinyin-upper">{{ item.pinyin.toUpperCase() }}</span>
+  <div class="content-left">
+    <div
+      class="content-left-item go-transition-quick go-mb-0"
+      span="12 1000:6 1400:4 1800:4 2200:2"
+      v-for="(item, index) in designColorRecommend"
+      :key="index"
+      @click="colorSelectHandle(item)"
+    >
+      <n-space>
+        <div class="content-left-item-color" :style="{ backgroundColor: item.hex }" />
+        <n-space vertical>
+          <n-space>
+            <span :style="{ color: item.hex }">{{ item.name }}</span>
+            <span class="Pinyin-upper">{{ item.pinyin.toUpperCase() }}</span>
+          </n-space>
+          <n-text>
+            {{ item.hex }}
+            <n-divider vertical />
+            {{
+              `rgb(${item.RGB[0]}, ${item.RGB[1]}, ${item.RGB[2]})`
+            }}
+          </n-text>
         </n-space>
-        <n-text>
-          {{ item.hex }}
-          <n-divider vertical />
-          {{
-            `rgb(${item.RGB[0]}, ${item.RGB[1]}, ${item.RGB[2]})`
-          }}
-        </n-text>
       </n-space>
-    </n-space>
-  </div>
-  <n-divider/>
-  <div
-    class="content-left-item go-transition-quick"
-    span="12 1000:6 1400:4 1800:4 2200:2"
-    v-for="(item, index) in designColor"
-    :key="index"
-    @click="colorSelectHandle(item)"
-  >
-    <n-space>
-      <div class="content-left-item-color" :style="{ backgroundColor: item.hex }" />
-      <n-space vertical>
-        <n-space>
-          <span :style="{ color: item.hex }">{{ item.name }}</span>
-          <span class="Pinyin-upper">{{ item.pinyin.toUpperCase() }}</span>
+    </div>
+    <n-divider />
+    <div
+      class="content-left-item go-transition-quick"
+      span="12 1000:6 1400:4 1800:4 2200:2"
+      v-for="(item, index) in designColor"
+      :key="index"
+      @click="colorSelectHandle(item)"
+    >
+      <n-space>
+        <div class="content-left-item-color" :style="{ backgroundColor: item.hex }" />
+        <n-space vertical>
+          <n-space>
+            <span :style="{ color: item.hex }">{{ item.name }}</span>
+            <span class="Pinyin-upper">{{ item.pinyin.toUpperCase() }}</span>
+          </n-space>
+          <n-text>
+            {{ item.hex }}
+            <n-divider vertical />
+            {{
+              `rgb(${item.RGB[0]}, ${item.RGB[1]}, ${item.RGB[2]})`
+            }}
+          </n-text>
         </n-space>
-        <n-text>
-          {{ item.hex }}
-          <n-divider vertical />
-          {{
-            `rgb(${item.RGB[0]}, ${item.RGB[1]}, ${item.RGB[2]})`
-          }}
-        </n-text>
       </n-space>
-    </n-space>
+    </div>
   </div>
 </template>
 
 <script lang="ts" setup>
+import { PropType } from 'vue'
 import { AppThemeColorType } from '@/store/modules/designStore/designStore.d'
-import designColor from '@/settings/designColor.json'
 import designColorRecommend from '@/settings/designColorRecommend.json'
 
 const emits = defineEmits(['colorSelectHandle'])
-
+defineProps({
+  designColor: {
+    type: Object as PropType<AppThemeColorType[]>,
+    required: true
+  }
+})
 const colorSelectHandle = (color: AppThemeColorType) => {
   emits('colorSelectHandle', color)
 }
 </script>
 
 <style lang="scss" scoped>
-.content-left-item {
-  position: relative;
+.content-left {
   display: flex;
-  margin-bottom: 10px;
-  margin-right: 10px;
-  padding: 10px 20px;
-  min-width: 300px;
-  border-radius: 5px;
-  cursor: pointer;
-  border: 1px solid rgba(0, 0, 0, 0);
-  &:hover {
-    @include hover-border-color("background-color5");
-  }
-  &::after {
-    content: "";
-    z-index: -1;
-    position: absolute;
-    top: 0;
-    left: 0;
-    width: 100%;
-    height: 100%;
-    opacity: 0.7;
-    overflow: hidden;
+  flex-wrap: wrap;
+  margin-right: 200px;
+  .content-left-item {
+    position: relative;
+    display: flex;
+    margin-bottom: 10px;
+    margin-right: 10px;
+    padding: 10px 20px;
+    min-width: 300px;
     border-radius: 5px;
-    @extend .go-background-filter-shallow;
-  }
-  &-color {
-    width: 8px;
-    height: 40px;
-    border-radius: 2px;
-  }
-  .Pinyin-upper {
-    font-size: 8px;
+    cursor: pointer;
+    border: 1px solid rgba(0, 0, 0, 0);
+    &:hover {
+      @include hover-border-color("background-color5");
+    }
+    &::after {
+      content: "";
+      z-index: -1;
+      position: absolute;
+      top: 0;
+      left: 0;
+      width: 100%;
+      height: 100%;
+      opacity: 0.7;
+      overflow: hidden;
+      border-radius: 5px;
+      @extend .go-background-filter-shallow;
+    }
+    &-color {
+      width: 8px;
+      height: 40px;
+      border-radius: 2px;
+    }
+    .Pinyin-upper {
+      font-size: 8px;
+    }
   }
 }
 </style>

+ 30 - 13
src/components/ThemeColorSelect/index.vue

@@ -13,12 +13,10 @@
         </n-icon>
       </n-space>
       <n-divider />
-      <div class="model-content">
-        <n-scrollbar>
-          <div class="content-left">
-            <ColorList @colorSelectHandle="colorSelectHandle" />
-          </div>
-        </n-scrollbar>
+      <div class="model-content" ref="contentLeftRef">
+        <div class="content-left" v-if="modelShow">
+          <ColorList :designColor="designColorSplit" @colorSelectHandle="colorSelectHandle" />
+        </div>
         <div class="content-right">
           <div class="color-name-detail">
             <n-text v-if="appThemeDetail" class="color-name">{{ appThemeDetail.name }}</n-text>
@@ -45,20 +43,31 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, computed } from 'vue'
+import { ref, computed, watch, toRefs } from 'vue'
 import { useDesignStore } from '@/store/modules/designStore/designStore'
 import { AppThemeColorType } from '@/store/modules/designStore/designStore.d'
 import { icon } from '@/plugins'
 import themeColorLogo from '@/assets/images/exception/theme-color.png'
 import { loadAsyncComponent } from '@/utils'
+import { useScroll } from '@vueuse/core'
+import designColor from '@/settings/designColor.json'
 
 const ColorList = loadAsyncComponent(() =>
   import('./components/ColorList.vue')
 )
 const { ColorWandIcon, CloseIcon } = icon.ionicons5
 
+let splitNumber = 50
+
 const designStore = useDesignStore()
 const modelShow = ref(false)
+const contentLeftRef = ref<HTMLElement | null>(null)
+const designColorSplit = ref(designColor.slice(0, splitNumber))
+
+const { arrivedState } = useScroll(contentLeftRef, {
+  offset: { bottom: 200 },
+})
+const { bottom } = toRefs(arrivedState)
 
 const appThemeDetail = computed(() => {
   return designStore.getAppThemeDetail
@@ -67,6 +76,19 @@ const appThemeDetail = computed(() => {
 const colorSelectHandle = (color: AppThemeColorType) => {
   designStore.setAppColor(color)
 }
+
+watch(() => bottom.value, (newData: boolean) => {
+  if (newData) {
+    splitNumber = splitNumber + 50
+    designColorSplit.value = designColor.slice(0, splitNumber)
+  }
+})
+
+watch(() => modelShow.value, (modelShow: boolean) => {
+  if (!modelShow) {
+    splitNumber = 50
+  }
+})
 </script>
 
 <style lang="scss" scoped>
@@ -89,12 +111,7 @@ $height: 85vh;
   .model-content {
     flex: 1;
     height: calc(#{$height} - 40px - 48px - 36px);
-    /* 左侧 */
-    .content-left {
-      display: flex;
-      flex-wrap: wrap;
-      margin-right: 200px;
-    }
+    overflow: auto;
     /* 右侧 */
     .content-right {
       position: absolute;

+ 17 - 1
src/styles/common/format.scss

@@ -1,3 +1,19 @@
 body {
   overflow: hidden;
-}
+}
+
+/* 设置滚动条的样式 */
+::-webkit-scrollbar {
+  width: 8px;
+}
+/* 滚动槽 */
+::-webkit-scrollbar-track {
+  -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0);
+  border-radius: 2px;
+}
+/* 滚动条滑块 */
+::-webkit-scrollbar-thumb {
+  border-radius: 4px;
+  background: #a3a3a3;
+}
+