소스 검색

feat: 列表宽度拖拽保存到缓存

liujt 1 주 전
부모
커밋
2f78e82366

+ 2 - 1
src/BIZComponents/selectStockLedger/selectStockLedgerDialog.vue

@@ -53,6 +53,7 @@
             :cache-key="cacheKeyUrl"
             :page-size="20"
             @columns-change="handleColumnChange"
+            @header-dragend="handleHeaderDragend"
           >
             <template v-slot:saleCount="{ row }">
               <el-input
@@ -334,7 +335,7 @@
             align: 'center'
           }
         ];
-        return tempData.filter((item) => !item.hide);
+        return this.applyColumnWidth(tempData.filter((item) => !item.hide));
       }
     },
     methods: {

+ 45 - 38
src/mixins/tableColumnsMixin.js

@@ -5,7 +5,9 @@ export default {
   data() {
     return {
       newColumns: [],
-      tabMixinsInit: true //进入页面是否默认请求列配置
+      tabMixinsInit: true, //进入页面是否默认请求列配置
+      // 列宽映射(prop/columnKey -> 宽度),用于 computed columns 应用拖拽/缓存后的宽度
+      columnWidthMap: {}
     };
   },
   created() {
@@ -80,17 +82,9 @@ export default {
           this.saveColumns(uniqueLabelList);
         }
         this.setStorage(this.cacheKeyUrl + 'Cols', nlist);
-        // 从缓存恢复列宽到本地列(下次进入生效)
+        // 从缓存恢复列宽到 columnWidthMap,并应用到列
         this.applyColumnWidthFromCache();
-        // 更新列
-        if (this._computedWatchers && this._computedWatchers.columns) {
-          // console.log('columns 是计算属性');
-          this.columnsVersion++;
-        } else {
-          // console.log('columns 是 data 属性');
-          this.columns = [...this.columns];
-          this.newColumns = [...this.newColumns];
-        }
+        this.applyColumnWidths();
       }
     },
     getColumns() {
@@ -119,23 +113,43 @@ export default {
       loop(this.getColumns() || []);
       return result;
     },
-    // 表头拖拽列宽变化回调:更新本地列并持久化
+    // 表头拖拽列宽变化回调:更新列宽映射并持久化
     handleHeaderDragend(newWidth, oldWidth, column) {
       if (!column || !newWidth) return;
       const key = column.property || column.columnKey;
-      const label = column.label;
-      const target = this.findColumnByKey(key, label);
-      if (target) {
-        target.width = newWidth;
-        // 触发 ele-pro-table 重新渲染(render 时 props 会带上 width)
-        if (this._computedWatchers && this._computedWatchers.columns) {
-          this.columnsVersion++;
-        } else {
-          this.columns = [...this.columns];
-        }
-      }
+      if (!key) return;
+      // 仅持久化新宽度,不触发 columns 重算。
+      // el-table 在拖拽过程中已实时更新列宽,此处重算会导致整表重渲染抖动;
+      // 刷新后由 applyColumnWidthFromCache 从缓存恢复,无需拖拽时同步映射。
       this.persistColumnWidth(key, newWidth);
     },
+    // 应用列宽并触发表格更新(自动区分 columns 是 computed 还是 data)
+    applyColumnWidths() {
+      const isComputed = !!(this._computedWatchers && this._computedWatchers.columns);
+      if (isComputed) {
+        // computed 场景:columns 内部已调用 applyColumnWidth,这里只需触发重算
+        this.columnsVersion++;
+      } else {
+        // data 场景:直接应用宽度到 data 数组并触发更新
+        this.applyColumnWidth(this.columns);
+        this.columns = [...this.columns];
+      }
+    },
+    // 应用列宽映射到列数组(供 computed columns 生成列后调用,或 data columns 直接应用)
+    applyColumnWidth(columns) {
+      const map = this.columnWidthMap || {};
+      const keys = Object.keys(map);
+      if (!keys.length || !columns) return columns;
+      const loop = (cols) => {
+        (cols || []).forEach((col) => {
+          const k = col.prop || col.columnKey;
+          if (k && map[k] != null) this.$set(col, 'minWidth', map[k]);
+          if (col.children && col.children.length) loop(col.children);
+        });
+      };
+      loop(columns);
+      return columns;
+    },
     // 持久化列宽到列设置(localStorage 与 ele-pro-table 共用 cacheKey+'Cols',并同步服务端)
     persistColumnWidth(key, width) {
       if (!key) return;
@@ -143,7 +157,7 @@ export default {
       const cached = this.getStorage(storageKey) || [];
       const setting = cached.find((c) => (c.columnKey || c.prop || c.id) === key);
       if (setting) {
-        setting.width = width;
+        setting.minWidth = width;
       } else {
         cached.push({
           id: key,
@@ -151,7 +165,7 @@ export default {
           columnKey: key,
           label: key,
           checked: true,
-          width
+          minWidth: width
         });
       }
       this.setStorage(storageKey, cached);
@@ -159,23 +173,15 @@ export default {
         this.debouncedSaveColumns(cached);
       }
     },
-    // 从缓存恢复列宽到本地列(下次进入页面时调用)
+    // 从缓存恢复列宽到 columnWidthMap(供 computed columns 应用)
     applyColumnWidthFromCache() {
       const cached = this.getStorage(this.cacheKeyUrl + 'Cols') || [];
-      const widthMap = {};
       cached.forEach((c) => {
         const k = c.columnKey || c.prop || c.id;
-        if (k && c.width != null) widthMap[k] = c.width;
+        if (k && c.minWidth != null) {
+          this.$set(this.columnWidthMap, k, c.minWidth);
+        }
       });
-      if (!Object.keys(widthMap).length) return;
-      const loop = (cols) => {
-        (cols || []).forEach((col) => {
-          const k = col.columnKey || col.prop;
-          if (k && widthMap[k] != null) col.width = widthMap[k];
-          if (col.children && col.children.length) loop(col.children);
-        });
-      };
-      loop(this.getColumns());
     },
     //服务器和本地配置columns对比
     columnsContrast(list) {
@@ -328,6 +334,7 @@ export default {
       } catch (error) {
         console.error('保存列配置失败:', error);
       }
-    }
+    },
+    
   }
 };

+ 6 - 2
src/views/saleManage/saleOrder/index.vue

@@ -49,6 +49,7 @@
                 :cache-key="cacheKeyUrl"
                 show-summary
                 :summary-method="getSummaries"
+                @header-dragend="handleHeaderDragend"
               >
                 <!-- 表头工具栏 -->
                 <template v-slot:toolbar>
@@ -673,7 +674,8 @@ export default {
     },
     columns() {
       let columnsVersion = this.columnsVersion;
-      return [
+       
+      const list = [
         {
           width: 45,
           type: 'selection',
@@ -1014,6 +1016,8 @@ export default {
           fixed: 'right'
         }
       ];
+
+      return this.applyColumnWidth(list);
     }
   },
   watch: {
@@ -1163,7 +1167,7 @@ export default {
     },
     /* 表格数据源 */
     datasource({ page, limit, where, order }) {
-      console.log('where~~~', where);
+      console.log('where~~~', where, limit);
       if(where?.needProduces?.length){
         where['needProduces'] = where.needProduces.join(',');
       }

+ 1 - 0
src/views/saleManage/saleOrder/invoice/index.vue

@@ -26,6 +26,7 @@
               children: 'children',
               hasChildren: 'hasChildren'
             }"
+            @header-dragend="handleHeaderDragend"
           >
             <!-- 表头工具栏 -->
             <template v-slot:toolbar>