From c9251999e5373e7674dd502c3bcbb18770c1f6aa Mon Sep 17 00:00:00 2001
From: lxf <1371462558@qq.com>
Date: Wed, 16 Jul 2025 17:13:16 +0800
Subject: [PATCH] 首屏加载骨架屏

---
 src/views/news/index.vue |   74 +++++++++++++++++++++----------------
 vite.config.js           |    8 +++
 2 files changed, 49 insertions(+), 33 deletions(-)

diff --git a/src/views/news/index.vue b/src/views/news/index.vue
index 48a90eb..db4c777 100644
--- a/src/views/news/index.vue
+++ b/src/views/news/index.vue
@@ -1,23 +1,5 @@
 <template>
-  <!-- <section class="inner-tab-container"> -->
-  <!-- <p class="title">{{ t('news') }}</p> -->
-  <!-- <div class="news-container"> -->
-  <!-- <van-steps direction="vertical" :active="0" active-color="#fff"> -->
-  <!-- <van-step v-for="(item, index) in list" :key="item.uuid || index">
-          <p class="time">{{ item.createTime }}</p>
-          <p class="context">{{ item.description }}</p>
-        </van-step> -->
-  <!-- <van-step>
-          <p class="time">2023-06-15 11:30</p>
-          <p class="context">南非汇市:兰特兑美元走高,美国通胀报告发布后美元跌至约两周地点</p>
-        </van-step>
-        <van-step>
-          <p class="time">2023-06-14 14:20</p>
-          <p class="context">降息预期遭重挫败!CPI环比增速抬头 美联储抗通胀之路注定崎岖</p>
-        </van-step> -->
-  <!-- </van-steps> -->
-  <!-- </div> -->
-  <!-- </section> -->
+
   <!-- 顶部用户信息栏 -->
   <div class="flex items-center justify-between px-17 pt-10">
     <div class="text-20 font-bold">{{ username }}</div>
@@ -31,10 +13,14 @@
   <!-- 热门货币卡片部分 -->
   <div class="mt-10">
     <div class="block text-22 font-medium px-17">{{ t('热门') }}</div>
-    <div class="flex overflow-x-auto mt-10 px-17">
-      <!-- DOGE/USDT 卡片 -->
-      <div class="w-140 h-160 mr-10 flex-none rounded-15 text-black" v-for="(item, index) in hotItems" :key="item"
-        :class="index % 2 === 1 ? 'bg-#9f9cff' : 'bg-#d8f0dd'">
+    <div v-if="isLoading" class="flex overflow-x-auto mt-10 px-17">
+      <Skeleton v-for="i in 3" :key="i" class="w-140 h-160 mr-10 flex-none rounded-15" title :row="4" animated
+        :loading="isLoading"></Skeleton>
+    </div>
+    <div v-else class="flex overflow-x-auto mt-10 px-17">
+      <!-- DOGE/USDT 卡片  -->
+      <div class="w-140 h-160 mr-10 flex-none rounded-15 text-black" v-for="(item, index) in hotItems"
+        :key="item.uuid || index" :class="index % 2 === 1 ? 'bg-#9f9cff' : 'bg-#d8f0dd'">
         <div class="py-17 px-13">
           <div class="font-bold block text-18">{{ item.name }}</div>
           <div class="font-bold block text-20">{{ item.ask }}</div>
@@ -61,13 +47,13 @@
   <div class="flex justify-between text-12 mt-20">
     <div class="flex-1 flex flex-col items-center" @click="goToPage('/mining')">
       <div class="w-40 h-40 rounded-full flex items-center justify-center">
-        <img class="w-33 h-33" src="@/assets/a.jpg" draggable="false">
+        <img class="w-33 h-33" src="@/assets/a.jpg" draggable="false" width="33" height="33">
       </div>
       <div class="text-center">{{ t('理财') }}</div>
     </div>
     <div class="flex-1 flex flex-col items-center" @click="goToPage('/cryptos/trade/USDSGD')">
       <div class="w-40 h-40 rounded-full flex items-center justify-center">
-        <img class="w-33 h-33" src="@/assets/c.jpg" draggable="false">
+        <img class="w-33 h-33" src="@/assets/c.jpg" draggable="false" width="33" height="33">
       </div>
       <div class="text-center">{{ t('外汇交易') }}</div>
     </div>
@@ -102,13 +88,25 @@
     <div class="flex items-end justify-between px-17">
       <span class="block text-22 font-medium">{{ t('news') }}</span>
     </div>
-    <div class="px-17 mt-10">
+    <div v-if="isLoading" class="px-17 mt-10 space-y-10">
+      <div v-for="i in 3" :key="i" class="rounded-5 overflow-hidden">
+        <div class="py-12 px-15 flex items-center space-x-4">
+          <Skeleton class="flex-1" title :row="1" :loading="isLoading"></Skeleton>
+          <Skeleton class="w-20 h-16 rounded-10" animated :loading="isLoading"></Skeleton>
+        </div>
+        <div class="mt-5 px-15">
+          <Skeleton class="w-1/4" :row="1" animated :loading="isLoading"></Skeleton>
+        </div>
+      </div>
+    </div>
+    <div v-else class="px-17 mt-10">
       <!-- 新闻条目1 -->
       <div class="rounded-5 overflow-hidden mb-10" v-for="(t) in list" :key="t.dataId">
         <div class="bg-#f5f7f9 py-12 px-15 ">
           <div class="flex" style="border-bottom: 1px solid rgb(209, 209, 209);">
             <div class="text-12 h-70 flex-1 line3">{{ t.title }}</div>
-            <img class="w-90 h-55 flex-none rounded-10 ml-10" :src="t.imgUrl" draggable="false">
+            <img class="w-90 h-55 flex-none rounded-10 ml-10" :src="t.imgUrl" loading="lazy" width="90" height="55"
+              draggable="false">
           </div>
           <div class="mt-5 text-10 text-#8c8c8c flex justify-between">
             <span>{{ t.createTime }}</span>
@@ -122,7 +120,8 @@
 </template>
 
 <script setup>
-import { ref, onMounted, onUnmounted } from 'vue';
+import { ref, onMounted, onUnmounted, computed } from 'vue';
+import { Skeleton } from 'vant';
 import { _getInformationList } from '@/service/etf.api'
 import { _getHomeList } from '@/service/cryptos.api'
 import { showToast } from 'vant'
@@ -135,6 +134,9 @@
 const { t } = useI18n()
 const list = ref([])
 const hotItems = ref([]) // 热门
+const infoLoading = ref(true);
+const homeLoading = ref(true);
+const isLoading = computed(() => infoLoading.value || homeLoading.value);
 const username = ref('')
 const usercode = ref('')
 
@@ -144,13 +146,19 @@
 
   // 从localStorage获取用户信息
   const user = JSON.parse(localStorage.getItem('user'))
-  console.log('user', user)
+
   username.value = user.userInfo?.username || ''
   usercode.value = user.userInfo?.usercode || ''
 
   // 如果本地没有 coins,拉取接口
-  const quotesData = await _getCoinList()
-  setStorage('qoutes', { coins: quotesData }) // 存到本地
+  const cachedQuotes = localStorage.getItem('qoutes');
+  let quotesData;
+  if (cachedQuotes) {
+    quotesData = JSON.parse(cachedQuotes).coins;
+  } else {
+    quotesData = await _getCoinList();
+    setStorage('qoutes', { coins: quotesData }); // 仅在获取新数据时更新缓存
+  }
 })
 
 const goToExplanation = () => {
@@ -174,6 +182,7 @@
 const getInformationList = () => {
   _getInformationList().then(data => {
     list.value = data
+    infoLoading.value = false
   })
 }
 
@@ -187,13 +196,14 @@
   const fetchData = () => {
     _getHomeList().then(data => {
       hotItems.value = data.slice(0, 3) // 取前3条数据
+      homeLoading.value = false
     })
   }
 
   // 立即执行一次
   fetchData()
 
-  intervalId.value = setInterval(fetchData, 1000)
+  intervalId.value = setInterval(fetchData, 2000)
 
   onUnmounted(() => {
     if (intervalId.value) {
diff --git a/vite.config.js b/vite.config.js
index 0f9037d..6fd1060 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -56,6 +56,8 @@
   },
   build: {
     assetsDir: "static",
+    sourcemap: false,
+    cssCodeSplit: true,
     rollupOptions: {
       input: {
         index: path.resolve(__dirname, "index.html"),
@@ -63,7 +65,11 @@
       output: {
         chunkFileNames: 'js/[name]-[hash].js',
         entryFileNames: "js/[name]-[hash].js",
-        assetFileNames: "[ext]/name-[hash].[ext]"
+        assetFileNames: "[ext]/[name]-[hash].[ext]",
+        manualChunks: {
+          vendor: ['vue', 'vue-router', 'vue-i18n'],
+          vant: ['vant']
+        }
       },
     },
   },

--
Gitblit v1.9.3