فهرست منبع

1、优化初始化加载

yys 4 هفته پیش
والد
کامیت
32f1fecc82
6فایلهای تغییر یافته به همراه215 افزوده شده و 183 حذف شده
  1. 4 3
      babel.config.js
  2. 4 4
      src/assets/styles/transition.scss
  3. 2 1
      src/layout/components/AppMain.vue
  4. 1 2
      src/router/index.js
  5. 200 169
      src/views/components/index/statisticsDashboard.vue
  6. 4 4
      vue.config.js

+ 4 - 3
babel.config.js

@@ -5,9 +5,10 @@ module.exports = {
   ],
   'env': {
     'development': {
-      // babel-plugin-dynamic-import-node plugin only does one thing by converting all import() to require().
-      // This plugin can significantly increase the speed of hot updates, when you have a large number of pages.
-      'plugins': ['dynamic-import-node']
+      // 关闭 dynamic-import-node:它会把 import() 变成同步 require,
+      // 导致首页仪表盘、异步组件在开发环境也同步加载,首屏/切页明显变慢。
+      // 若本地 HMR 过慢可再临时打开。
+      'plugins': []
     }
   }
 }

+ 4 - 4
src/assets/styles/transition.scss

@@ -11,20 +11,20 @@
   opacity: 0;
 }
 
-/* fade-transform */
+/* fade-transform:缩短动画,避免切模块体感卡顿 */
 .fade-transform-leave-active,
 .fade-transform-enter-active {
-  transition: all .5s;
+  transition: all .18s;
 }
 
 .fade-transform-enter {
   opacity: 0;
-  transform: translateX(-30px);
+  transform: translateX(-10px);
 }
 
 .fade-transform-leave-to {
   opacity: 0;
-  transform: translateX(30px);
+  transform: translateX(10px);
 }
 
 /* breadcrumb transition */

+ 2 - 1
src/layout/components/AppMain.vue

@@ -1,6 +1,7 @@
 <template>
   <section class="app-main">
-    <transition name="fade-transform" mode="out-in">
+    <!-- 去掉 mode="out-in":原先离开动画结束才进入,每次切模块额外白等约 0.5~1s -->
+    <transition name="fade-transform">
       <keep-alive :include="cachedViews">
         <router-view :key="key" />
       </keep-alive>

+ 1 - 2
src/router/index.js

@@ -5,7 +5,6 @@ Vue.use(Router)
 
 /* Layout */
 import Layout from '@/layout'
-import LiveConsole from "@/views/live/liveConsole/index.vue";
 
 
 /**
@@ -234,7 +233,7 @@ export const constantRoutes = [
   {
     path: '/live/liveConsole/:liveId',
     name: 'LiveConsole',
-    component: LiveConsole, // 直接渲染目标组件,无侧边栏
+    component: () => import('@/views/live/liveConsole/index.vue'),
     meta: {
       isIndependentPage: true // 标记为“独立页”
     }

+ 200 - 169
src/views/components/index/statisticsDashboard.vue

@@ -17,7 +17,7 @@
               </div>
 
               <div class="card-value highlight1">
-                <count-to :start-val="0" :end-val="dealderCount" :duration="3600"
+                <count-to :start-val="0" :end-val="dealderCount" :duration="800"
                           class="card-panel-num companynumber" />
               </div>
             </div>
@@ -27,7 +27,7 @@
                 销售数量
               </div>
               <div class="card-value highlight1">
-                <count-to :start-val="0" :end-val="groupMgrCount" :duration="3600"
+                <count-to :start-val="0" :end-val="groupMgrCount" :duration="800"
                           class="card-panel-num companynumber" />
               </div>
             </div>
@@ -37,7 +37,7 @@
                 会员数量
               </div>
               <div class="card-value highlight1">
-                <count-to :start-val="0" :end-val="memberCount" :duration="3600" class="card-panel-num companynumber" />
+                <count-to :start-val="0" :end-val="memberCount" :duration="800" class="card-panel-num companynumber" />
                 <span class="highlight-today-add companyadd">+{{todayIncreaseUserNum}}</span>
               </div>
 
@@ -48,7 +48,7 @@
                 企微数量
               </div>
               <div class="card-value highlight1">
-                <count-to :start-val="0" :end-val="qwMemberNum" :duration="3600" class="card-panel-num companynumber" />
+                <count-to :start-val="0" :end-val="qwMemberNum" :duration="800" class="card-panel-num companynumber" />
               </div>
             </div>
             <div class="botttombg companycard">
@@ -57,7 +57,7 @@
                 pad使用情况
               </div>
               <div class="card-value highlight1">
-                <count-to :start-val="0" :end-val="padUsedNum" :duration="3600" class="card-panel-num companynumber" />
+                <count-to :start-val="0" :end-val="padUsedNum" :duration="800" class="card-panel-num companynumber" />
                 /
                 <template v-if="typeof padTotalNum === 'number'">
                   <count-to :start-val="0" :end-val="padTotalNum" :duration="1800" class="card-panel-num companynumber" />
@@ -82,7 +82,7 @@
                 企业资产(元)
               </div>
               <div class="card-value highlight">
-                <count-to :start-val="0" :end-val="balance" :duration="3600" class="card-panel-num" />
+                <count-to :start-val="0" :end-val="balance" :duration="800" class="card-panel-num" />
               </div>
             </div>
             <div class="property-card propertyline">
@@ -91,7 +91,7 @@
                 润天余额(元)
               </div>
               <div class="card-value highlight">
-                <count-to :start-val="0" :end-val="runTianBalance" :duration="3600" class="card-panel-num" />
+                <count-to :start-val="0" :end-val="runTianBalance" :duration="800" class="card-panel-num" />
               </div>
             </div>
             <div class="property-card">
@@ -99,7 +99,7 @@
                 <span>今日消耗 (元)</span>
               </div>
               <div class="card-value highlight" style="color: rgba(32, 33, 36, 1);margin-top: 10px;">
-                <count-to :start-val="0" :end-val="todayComsumption" :duration="3600" class="card-panel-num" />
+                <count-to :start-val="0" :end-val="todayComsumption" :duration="800" class="card-panel-num" />
               </div>
               <div class="card-compare">
                 较昨日 <span>+1</span>
@@ -122,7 +122,7 @@
                 收款总数
               </div>
               <div class="operate-value highlight">
-                <count-to :start-val="0" :end-val="recvTotalNum" :duration="3600" class="card-panel-num" />
+                <count-to :start-val="0" :end-val="recvTotalNum" :duration="800" class="card-panel-num" />
                 <div class="yesterdaybox">
                   较昨日 <span class="highlight-today-add2">+{{recvTodayNum}}</span>
                 </div>
@@ -136,7 +136,7 @@
                 订单总数
               </div>
               <div class="operate-value highlight">
-                <count-to :start-val="0" :end-val="orderTotalNum" :duration="3600" class="card-panel-num" />
+                <count-to :start-val="0" :end-val="orderTotalNum" :duration="800" class="card-panel-num" />
                 <div class="yesterdaybox">
                   较昨日 <span class="highlight-today-add2">+{{todayOrderNum}}</span>
                 </div>
@@ -151,15 +151,15 @@
                 平台今日看课人数
               </div>
               <div class="operate-value highlight">
-                <count-to :start-val="0" :end-val="todayWatchUserCount" :duration="3600" class="card-panel-num" />
+                <count-to :start-val="0" :end-val="todayWatchUserCount" :duration="800" class="card-panel-num" />
               </div>
               <div class="card-sub">
                 <span>配额上限</span>
                 <span class="sub-value">
-                  <count-to :start-val="0" :end-val="todayWatchUserCount" :duration="3600" class="card-panel-num"
+                  <count-to :start-val="0" :end-val="todayWatchUserCount" :duration="800" class="card-panel-num"
                             style="color: rgba(49, 185, 154, 1);" />
                   /
-                  <count-to :start-val="0" :end-val="versionLimit" :duration="3600" class="card-panel-num" />
+                  <count-to :start-val="0" :end-val="versionLimit" :duration="800" class="card-panel-num" />
                 </span>
               </div>
               <el-progress :percentage="versionLimitPercent" :show-text="false"
@@ -171,7 +171,7 @@
                 商品总数
               </div>
               <div class="operate-value highlight">
-                <count-to :start-val="0" :end-val="goodsTotalNum" :duration="3600" class="card-panel-num" />
+                <count-to :start-val="0" :end-val="goodsTotalNum" :duration="800" class="card-panel-num" />
                 <div class="yesterdaybox">
                   较昨日 <span class="highlight-today-add2">+{{todayGoodsNum}}</span>
                 </div>
@@ -296,13 +296,13 @@
                 <div class="card-row">
                   <span>观看人数</span>
                   <span class="highlight">
-                    <count-to :start-val="0" :end-val="watchUserCount" :duration="3600" class="card-panel-num" />
+                    <count-to :start-val="0" :end-val="watchUserCount" :duration="800" class="card-panel-num" />
                   </span>
                 </div>
                 <div class="card-row">
                   <span>完播人数</span>
                   <span class="highlight">
-                    <count-to :start-val="0" :end-val="completedUserCount" :duration="3600" class="card-panel-num" />
+                    <count-to :start-val="0" :end-val="completedUserCount" :duration="800" class="card-panel-num" />
                   </span>
                 </div>
                 <div class="card-row">
@@ -317,12 +317,12 @@
                 <div class="card-row">
                   <span>观看次数</span>
                   <span class="highlight-red">
-                    <count-to :start-val="0" :end-val="watchCount" :duration="3600" class="card-panel-num" /></span>
+                    <count-to :start-val="0" :end-val="watchCount" :duration="800" class="card-panel-num" /></span>
                 </div>
                 <div class="card-row">
                   <span>完播次数</span>
                   <span class="highlight-red">
-                    <count-to :start-val="0" :end-val="completedCount" :duration="3600" class="card-panel-num" />
+                    <count-to :start-val="0" :end-val="completedCount" :duration="800" class="card-panel-num" />
                   </span>
                 </div>
                 <div class="card-row">
@@ -343,13 +343,13 @@
                 <div class="card-row">
                   <span>答题人数</span>
                   <span class="highlight-black">
-                    <count-to :start-val="0" :end-val="answerMemberCount" :duration="3600" class="card-panel-num" />
+                    <count-to :start-val="0" :end-val="answerMemberCount" :duration="800" class="card-panel-num" />
                   </span>
                 </div>
                 <div class="card-row">
                   <span>正确人数</span>
                   <span class="highlight-black">
-                    <count-to :start-val="0" :end-val="correctUserCount" :duration="3600" class="card-panel-num" />
+                    <count-to :start-val="0" :end-val="correctUserCount" :duration="800" class="card-panel-num" />
                   </span>
                 </div>
                 <div class="card-row">
@@ -370,13 +370,13 @@
                 <div class="card-row">
                   <span>答题红包个数</span>
                   <span class="highlight-black">
-                    <count-to :start-val="0" :end-val="rewardCount" :duration="3600" class="card-panel-num" />
+                    <count-to :start-val="0" :end-val="rewardCount" :duration="800" class="card-panel-num" />
                   </span>
                 </div>
                 <div class="card-row">
                   <span>答题红包金额(元)</span>
                   <span class="highlight-black">
-                    <count-to :start-val="0" :end-val="rewardMoney" :duration="3600" class="card-panel-num" /></span>
+                    <count-to :start-val="0" :end-val="rewardMoney" :duration="800" class="card-panel-num" /></span>
                 </div>
               </div>
             </div>
@@ -1055,27 +1055,30 @@ export default {
     }
   },
   mounted() {
+    this._onResize = () => {
+      this.viewerChart && this.viewerChart.resize()
+      this.dealerChart && this.dealerChart.resize()
+      this.dealerChartNew && this.dealerChartNew.resize()
+      this.courseWatchChart && this.courseWatchChart.resize()
+      this.answerRedPackViewerChart && this.answerRedPackViewerChart.resize()
+      this.answerRedPackMoneyViewerChart && this.answerRedPackMoneyViewerChart.resize()
+      this.thisMonthOrderChart && this.thisMonthOrderChart.resize()
+      this.thisMonthRecvChart && this.thisMonthRecvChart.resize()
+    }
     this.$nextTick(() => {
-      this.initViewerChart();
-      this.initDealerChartNew();
-      this.initDealerChart();
-      this.initCourseWatchChart();
-      this.initAnswerRedPackViewerChart();
-      this.initAnswerRedPackMoneyViewerChart();
-      this.initThisMonthOrderChart();
-      this.initThisMonthRecvChart();
-
-
-      // 监听窗口大小变化,重新渲染图表
-      window.addEventListener('resize', () => {
-        this.viewerChart && this.viewerChart.resize()
-        this.dealerChart && this.dealerChart.resize()
-        this.dealerChartNew && this.dealerChartNew.resize()
-      })
+      // 仅初始化当前可见分区图表,其余切 Tab 时再 init
+      this.ensureChartsForSelectedDiv()
+      window.addEventListener('resize', this._onResize)
     })
   },
   created() {
-    this.refresh();
+    // 首屏只拉卡片概览;图表数据延后,避免阻塞首页可交互
+    this.refreshOverview()
+    this.$nextTick(() => {
+      setTimeout(() => {
+        this.loadVisibleChartData()
+      }, 100)
+    })
     listDept().then(res => {
       this.deptInitOptions = res.data;
       listCompany().then(res => {
@@ -1153,6 +1156,126 @@ export default {
 
       this.refresh()
     },
+    /** 完整刷新:概览 + 当前可见图表(筛选条件变化时用) */
+    refresh() {
+      this.refreshOverview()
+      this.loadVisibleChartData()
+    },
+    /** 仅卡片/汇总数据,保证首页先可交互 */
+    refreshOverview() {
+      rechargeComsumption(this.staticParam).then(res => {
+        if (res.code === 200) {
+          this.balance = res.data.balance;
+          this.runTianBalance = res.data.runTianBalance;
+          this.todayComsumption = res.data.todayComsumption;
+          this.yesterdayComsumption = res.data.yesterdayComsumption;
+          let calculateRemainingDays1 = this.calculateRemainingDays(this.balance, this.todayComsumption, this.yesterdayComsumption);
+          this.percentage = calculateRemainingDays1.percentage;
+          this.remainMessage = calculateRemainingDays1.message;
+        }
+      });
+
+      trafficLog(this.staticParam).then(res => {
+        if (res.code === 200) {
+          this.todayTraffic = res.data.today;
+          this.thisMonthTraffic = res.data.thisMonth;
+          this.trafficCount = res.data.traffic;
+        }
+      })
+
+      dealerAggregated(this.staticParam).then(res => {
+        if (res.code === 200) {
+          this.dealderCount = res.data.dealderCount ?? 0;
+          this.groupMgrCount = res.data.groupMgrCount ?? 0;
+          this.memberCount = res.data.memberCount ?? 0;
+          this.qwMemberNum = res.data.qwMemberNum ?? 0;
+          const totalNum = res.data.padTotalNum;
+          if(totalNum != null && totalNum !== -1 && totalNum > 0){
+            this.padTotalNum = totalNum;
+          }else{
+            this.padTotalNum = '不限';
+          }
+          this.padUsedNum = res.data.padUsedNum ?? 0;
+          this.padInfo = res.data.padInfo;
+          this.normalNum = res.data.normalNum ?? 0;
+          this.blackNum = res.data.blackNum ?? 0;
+          this.todayIncreaseUserNum = res.data.todayIncreaseUserNum ?? 0;
+          this.orderTotalNum = res.data.orderTotalNum ?? 0;
+          this.todayOrderNum = res.data.todayOrderNum ?? 0;
+          this.recvTotalNum = res.data.recvTotalNum ?? 0;
+          this.recvTodayNum = res.data.recvTodayNum ?? 0;
+          this.goodsTotalNum = res.data.goodsTotalNum ?? 0;
+          this.todayGoodsNum = res.data.todayGoodsNum ?? 0;
+        }
+      })
+      let param = this.getParam();
+
+      const today = dayjs();
+      param.startTime = this.formatDate(today);
+      param.endTime = this.formatDate(today);
+      analysisPreview(param).then(res => {
+        if (res.code === 200) {
+          this.watchUserCount = res.data.watchUserCount;
+          this.completedUserCount = res.data.completedUserCount;
+          this.completedRate = res.data.completedRate;
+          this.watchCount = res.data.watchCount;
+          this.completedCount = res.data.completedCount;
+          this.answerMemberCount = res.data.answerMemberCount;
+          this.correctUserCount = res.data.correctUserCount;
+          this.correctRate = res.data.correctRate;
+          this.rewardCount = res.data.rewardCount;
+          this.rewardMoney = res.data.rewardMoney;
+          this.watchRate = res.data.watchRate;
+        }
+      })
+      smsBalance(this.staticParam).then(res => {
+        if (res.code === 200) {
+          if (res.data == null) {
+            this.smsRemainCount = 0;
+          } else {
+            this.smsRemainCount = res.data;
+          }
+        }
+      })
+      authorizationInfo(this.staticParam).then(res => {
+        if (res.code === 200 && res.data != null) {
+          this.todayWatchUserCount = res.data.todayWatchUserCount;
+          this.versionLimit = res.data.versionLimit;
+          if(this.versionLimit){
+            this.versionLimitPercent = this.todayWatchUserCount/this.versionLimit;
+          }
+        }
+      })
+    },
+    /** 按当前 Tab 初始化图表实例 */
+    ensureChartsForSelectedDiv() {
+      if (this.selectedDiv === 0) {
+        this.initViewerChart()
+        this.initDealerChartNew()
+        this.initThisMonthOrderChart()
+        this.initThisMonthRecvChart()
+      } else if (this.selectedDiv === 1) {
+        this.initCourseWatchChart()
+      } else if (this.selectedDiv === 2) {
+        this.initAnswerRedPackViewerChart()
+        this.initAnswerRedPackMoneyViewerChart()
+      }
+    },
+    /** 只请求当前可见图表数据,避免一次打满十余个图表接口 */
+    loadVisibleChartData() {
+      this.ensureChartsForSelectedDiv()
+      if (this.selectedDiv === 0) {
+        this.handleViewChartData()
+        this.handleDealerChartDataNew()
+        this.handleThisMonthRecvCount()
+        this.handleThisMonthOrderCount()
+      } else if (this.selectedDiv === 1) {
+        this.handleCourseWatchChart()
+      } else if (this.selectedDiv === 2) {
+        this.handleAnswerRedPackViewerChart()
+        this.handleAnswerRedPackMoneyViewerChart()
+      }
+    },
     /**
      * 计算余额预计可持续的天数
      * @param {number} balance - 当前账户余额
@@ -1261,109 +1384,6 @@ export default {
         this.$message.info('已关闭自动刷新');
       }
     },
-    refresh() {
-      rechargeComsumption(this.staticParam).then(res => {
-        console.log(res);
-        if (res.code === 200) {
-          this.balance = res.data.balance;
-          this.runTianBalance = res.data.runTianBalance;
-          this.todayComsumption = res.data.todayComsumption;
-          this.yesterdayComsumption = res.data.yesterdayComsumption;
-          let calculateRemainingDays1 = this.calculateRemainingDays(this.balance, this.todayComsumption, this.yesterdayComsumption);
-          this.percentage = calculateRemainingDays1.percentage;
-          this.remainMessage = calculateRemainingDays1.message;
-        }
-      });
-
-      trafficLog(this.staticParam).then(res => {
-        if (res.code === 200) {
-          this.todayTraffic = res.data.today;
-          this.thisMonthTraffic = res.data.thisMonth;
-          this.trafficCount = res.data.traffic;
-        }
-      })
-
-      dealerAggregated(this.staticParam).then(res => {
-        if (res.code === 200) {
-          this.dealderCount = res.data.dealderCount ?? 0;
-          this.groupMgrCount = res.data.groupMgrCount ?? 0;
-          this.memberCount = res.data.memberCount ?? 0;
-          this.qwMemberNum = res.data.qwMemberNum ?? 0;
-          const totalNum = res.data.padTotalNum;
-          //-1 不限 null 未设置
-          if(totalNum != null && totalNum !== -1 && totalNum > 0){
-            this.padTotalNum = totalNum;
-          }else{
-            this.padTotalNum = '不限';
-          }
-          this.padUsedNum = res.data.padUsedNum ?? 0;
-          this.padInfo = res.data.padInfo;
-          this.normalNum = res.data.normalNum ?? 0;
-          this.blackNum = res.data.blackNum ?? 0;
-          this.todayIncreaseUserNum = res.data.todayIncreaseUserNum ?? 0;
-          this.orderTotalNum = res.data.orderTotalNum ?? 0;
-          this.todayOrderNum = res.data.todayOrderNum ?? 0;
-          this.recvTotalNum = res.data.recvTotalNum ?? 0;
-          this.recvTodayNum = res.data.recvTodayNum ?? 0;
-          this.goodsTotalNum = res.data.goodsTotalNum ?? 0;
-          this.todayGoodsNum = res.data.todayGoodsNum ?? 0;
-        }
-      })
-      let param = this.getParam();
-
-      // 获取当前日期时间
-      const today = dayjs();
-      param.startTime = this.formatDate(today);
-      param.endTime = this.formatDate(today);
-      analysisPreview(param).then(res => {
-        if (res.code === 200) {
-          this.watchUserCount = res.data.watchUserCount;
-          this.completedUserCount = res.data.completedUserCount;
-          this.completedRate = res.data.completedRate;
-          this.watchCount = res.data.watchCount;
-          this.completedCount = res.data.completedCount;
-          this.answerMemberCount = res.data.answerMemberCount;
-          this.correctUserCount = res.data.correctUserCount;
-          this.correctRate = res.data.correctRate;
-          this.rewardCount = res.data.rewardCount;
-          this.rewardMoney = res.data.rewardMoney;
-          this.watchRate = res.data.watchRate;
-        }
-      })
-      smsBalance(this.staticParam).then(res => {
-        if (res.code === 200) {
-          if (res.data == null) {
-            this.smsRemainCount = 0;
-          } else {
-            this.smsRemainCount = res.data;
-          }
-        }
-      })
-      authorizationInfo(this.staticParam).then(res => {
-        if (res.code === 200 && res.data != null) {
-          this.todayWatchUserCount = res.data.todayWatchUserCount;
-          this.versionLimit = res.data.versionLimit;
-          if(this.versionLimit){
-            this.versionLimitPercent = this.todayWatchUserCount/this.versionLimit;
-          }
-        }
-      })
-
-      this.handleCourseWatchChart()
-      this.handleViewChartData()
-      this.handleDealerChartDataNew()
-
-      // 经销商会员观看TOP10
-      this.handleDealerChartData()
-
-      this.handleAnswerRedPackViewerChart()
-
-      this.handleAnswerRedPackMoneyViewerChart()
-
-      this.handleThisMonthRecvCount();
-      this.handleThisMonthOrderCount();
-
-    },
     /**
      * 将数字添加千位分隔符
      * @param {number|string} num - 需要格式化的数字
@@ -1392,34 +1412,23 @@ export default {
     handleToggleDiv(selected) {
       this.selectedDiv = selected;
 
-      if (selected === 1) {
-        this.$nextTick(() => {
+      this.$nextTick(() => {
+        this.ensureChartsForSelectedDiv()
+        if (selected === 1) {
           if (this.courseWatchChart) {
             this.courseWatchChart.resize();
-          } else {
           }
-        });
-      } else if (selected === 0) {
-        this.$nextTick(() => {
+        } else if (selected === 0) {
           if (this.viewerChart) this.viewerChart.resize();
-          if (this.dealerChart) this.dealerChart.resize();
-        });
-      } else if (selected === 2) {
-        this.$nextTick(() => {
+          if (this.dealerChartNew) this.dealerChartNew.resize();
+          if (this.thisMonthOrderChart) this.thisMonthOrderChart.resize();
+          if (this.thisMonthRecvChart) this.thisMonthRecvChart.resize();
+        } else if (selected === 2) {
           if (this.answerRedPackViewerChart) this.answerRedPackViewerChart.resize();
           if (this.answerRedPackMoneyViewerChart) this.answerRedPackMoneyViewerChart.resize();
-        });
-      }
-      if (this.selectedDiv === 0) {
-        this.handleViewChartData()
-        this.handleDealerChartData()
-        this.handleDealerChartDataNew()
-      } else if (this.selectedDiv === 1) {
-        this.handleCourseWatchChart()
-      } else if (this.selectedDiv === 2) {
-        this.handleAnswerRedPackViewerChart()
-        this.handleAnswerRedPackMoneyViewerChart()
-      }
+        }
+        this.loadVisibleChartData()
+      });
     },
     formatDate(date) {
       return dayjs(date).format('YYYY-MM-DD');
@@ -1640,38 +1649,45 @@ export default {
 
     },
     initThisMonthOrderChart() {
+      if (this.thisMonthOrderChart || !this.$refs.viewerOrderChart) return
       this.thisMonthOrderChart = echarts.init(this.$refs.viewerOrderChart)
       this.thisMonthOrderChart.setOption(thisMonthOrderCountOption)
     },
     initThisMonthRecvChart() {
-
+      if (this.thisMonthRecvChart || !this.$refs.viewerReceiveChart) return
       this.thisMonthRecvChart = echarts.init(this.$refs.viewerReceiveChart)
       this.thisMonthRecvChart.setOption(thisMonthOrderCountOption)
     },
     initViewerChart() {
+      if (this.viewerChart || !this.$refs.viewerChart) return
       this.viewerChart = echarts.init(this.$refs.viewerChart)
       this.viewerChart.setOption(viewCharOption)
     },
     initDealerChartNew() {
+      if (this.dealerChartNew || !this.$refs.dealerChartNew) return
       this.dealerChartNew = echarts.init(this.$refs.dealerChartNew)
       this.dealerChartNew.setOption(dealerOptionNew)
     },
     initDealerChart() {
+      if (this.dealerChart || !this.$refs.dealerChart) return
       this.dealerChart = echarts.init(this.$refs.dealerChart)
 
       this.dealerChart.setOption(dealerOption)
     },
     initCourseWatchChart() {
+      if (this.courseWatchChart || !this.$refs.courseWatchChart) return
       this.courseWatchChart = echarts.init(this.$refs.courseWatchChart)
 
       this.courseWatchChart.setOption(courseWatchOption)
     },
     initAnswerRedPackViewerChart() {
+      if (this.answerRedPackViewerChart || !this.$refs.answerRedPackViewerChart) return
       this.answerRedPackViewerChart = echarts.init(this.$refs.answerRedPackViewerChart)
 
       this.answerRedPackViewerChart.setOption(redPackageOption)
     },
     initAnswerRedPackMoneyViewerChart() {
+      if (this.answerRedPackMoneyViewerChart || !this.$refs.answerRedPackMoneyViewerChart) return
       this.answerRedPackMoneyViewerChart = echarts.init(this.$refs.answerRedPackMoneyViewerChart)
 
       this.answerRedPackMoneyViewerChart.setOption(lineChartOption)
@@ -1684,10 +1700,25 @@ export default {
       clearInterval(this.timer);
       this.timer = null;
     }
-    // window.removeEventListener('resize', this.resizeHandler)
-    this.viewerChart && this.viewerChart.dispose()
-    this.dealerChart && this.dealerChart.dispose()
-    this.dealerChartNew && this.dealerChartNew.dispose()
+    if (this._onResize) {
+      window.removeEventListener('resize', this._onResize)
+      this._onResize = null
+    }
+    ;[
+      'viewerChart',
+      'dealerChart',
+      'dealerChartNew',
+      'courseWatchChart',
+      'answerRedPackViewerChart',
+      'answerRedPackMoneyViewerChart',
+      'thisMonthOrderChart',
+      'thisMonthRecvChart'
+    ].forEach(key => {
+      if (this[key]) {
+        this[key].dispose()
+        this[key] = null
+      }
+    })
   }
 }
 </script>

+ 4 - 4
vue.config.js

@@ -21,8 +21,8 @@ module.exports = {
   outputDir: 'dist',
   // 用于放置生成的静态资源 (js、css、img、fonts) 的;(项目打包之后,静态资源会放在这个文件夹下)
   assetsDir: 'static',
-  // 是否开启eslint保存检测,有效值:ture | false | 'error'
-  lintOnSave: process.env.NODE_ENV === 'development',
+  // 大项目下保存时全量 eslint 会拖慢热编译/首次进入模块,改为手动 lint
+  lintOnSave: false,
   // 如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建。
   productionSourceMap: false,
   // 需要Babel转译的依赖包(这些包使用了ES2020+语法如??、?.、数字分隔符等)
@@ -65,8 +65,8 @@ module.exports = {
     }
   },
   chainWebpack(config) {
-    config.plugins.delete('preload') // TODO: need test
-    config.plugins.delete('prefetch') // TODO: need test
+    // 保留 prefetch,让浏览器空闲时预取异步路由 chunk,加快页面切换
+    config.plugins.delete('preload')
 
     // set svg-sprite-loader
     config.module