Vue3 + TypeScript + Element Plus 使用【设置表格列宽,组合式函数 hook】在原有页面实现表格列宽设置本地持久化实例总结

发布于:2025-06-16 ⋅ 阅读:(20) ⋅ 点赞:(0)

一、入库查询,实现表格列宽设置本地持久化

MaterialInQuery.vue

在原有代码基础上,增加【设置表格列宽,组合式函数 hook】相关的增量代码

特点:

1、导入设置表格列宽,组合式函数 hook、表格扩展实例类型、表格列配置接口

2、const 表格实例对象、表格列配置列表

3、const 设置表格列宽,使用 ref 定义,const setTableColumnWidth = ref<any>(null);

4、onMounted、nextTick、将 useSetTableColumnWidth(...) 赋值给设置表格列宽

5、加载表格列宽 loadColumnWidth

6、el-table 设置 ref="tableRef"、@header-dragend="setTableColumnWidth?.saveColumnWidth"

7、拖动列宽变化时,自动触发@header-dragend,保存表格列宽到本地存储空间

<script setup lang="ts" name="MaterialInQuery">

......

import { useSetTableColumnWidth } from "@/hooks/useSetTableColumnWidth";
import type { ElTableExtendedInstance, IColumnConfig } from "@/interface";

......

// 表格实例对象
const tableRef = ref<ElTableExtendedInstance | null>(null);
// 表格列配置列表
const columnConfigs = ref<IColumnConfig[]>([
  { prop: "rkNo", label: "入库编号", width: 120 },
  { prop: "jzDatetime", label: "记账时间", width: 165 },
  { prop: "supplier", label: "供应厂商", width: 300 },
  { prop: "total", label: "入库总额", width: 120 },
  { prop: "remark", label: "备注信息", width: 250 }
]);
// 设置表格列宽,使用 ref 定义,先用 null 占位,然后在 onMounted 中,等待表格渲染完毕,再赋值 useTableColumnWidth 组合式函数 hook
const setTableColumnWidth = ref<any>(null);

......

onMounted(async () => {
  // 等待表格渲染完成
  await nextTick();
  // 对应 const setTableColumnWidth = ref<any>(null);
  if (tableRef.value) {
    setTableColumnWidth.value = useSetTableColumnWidth(tableRef, columnConfigs, ref("MaterialInQuery_rkMaster"));
  }
  // 加载表格列宽
  setTableColumnWidth.value?.loadColumnWidth();
});
</script>

<template>

......

      <el-table
        ref="tableRef"

        ......

        @header-dragend="setTableColumnWidth?.saveColumnWidth">

......

</template>

二、出库查询,实现表格列宽设置本地持久化

MaterialOutQuery.vue

在原有代码基础上,增加【设置表格列宽,组合式函数 hook】相关的增量代码

特点:

1、导入设置表格列宽,组合式函数 hook、表格扩展实例类型、表格列配置接口

2、const 表格实例对象、表格列配置列表

3、const 设置表格列宽,使用 computed 定义组合式函数 hook

4、onMounted、nextTick

5、加载表格列宽 loadColumnWidth

6、el-table 设置 ref="tableRef"、@header-dragend="setTableColumnWidth?.saveColumnWidth"

7、拖动列宽变化时,自动触发@header-dragend,保存表格列宽到本地存储空间

<script setup lang="ts" name="MaterialOutQuery">

......

import { useSetTableColumnWidth } from "@/hooks/useSetTableColumnWidth";
import type { ElTableExtendedInstance, IColumnConfig } from "@/interface";

......

// 表格实例对象
const tableRef = ref<ElTableExtendedInstance | null>(null);
// 表格列配置列表
const columnConfigs = ref<IColumnConfig[]>([
  { prop: "ckNo", label: "出库编号", width: 120 },
  { prop: "jzDatetime", label: "记账时间", width: 165 },
  { prop: "llDeptId", label: "领取部门", width: 300 },
  { prop: "total", label: "出库总额", width: 120 },
  { prop: "remark", label: "备注信息", width: 250 }
]);
// 设置表格列宽,使用 computed 定义组合式函数 hook,并且自动处理 null 情况
const setTableColumnWidth = computed(() => {
  return tableRef.value ? useSetTableColumnWidth(tableRef, columnConfigs, ref("MaterialOutQuery_ckMaster")) : null;
});

......

onMounted(async () => {
  // 等待表格渲染完成
  await nextTick();
  // 加载表格列宽
  setTableColumnWidth.value?.loadColumnWidth();
});
</script>

<template>

......

      <el-table
        ref="tableRef"

        ......

        @header-dragend="setTableColumnWidth?.saveColumnWidth">

......

</template>

 【设置表格列宽,组合式函数 hook】useSetTableColumnWidth.ts

import type { ElTableExtendedInstance, IColumnConfig } from "@/interface";
import { type TableColumnCtx } from "element-plus";
import { type Ref } from "vue";

/**
 * 设置表格列宽,组合式函数 hook
 * @param tableRef 表格实例对象
 * @param tableColumnConfigs 表格列配置列表
 * @param tableName 表格名称,名称前面加上路由前缀避免标识符重复,如:Reagent_reagent
 * @returns
 */
export const useSetTableColumnWidth = (
  tableRef: Ref<ElTableExtendedInstance | null>,
  tableColumnConfigs: Ref<IColumnConfig[]>,
  tableName: Ref<string>
) => {
  // 加载表格列宽
  const loadColumnWidth = () => {
    let columns = tableRef.value?.store.states.columns.value;
    if (!columns || !Array.isArray(columns)) return;
    for (let column of columns) {
      let prop = column.property;
      if (prop) {
        // 从本地存储中获取列宽
        let storageColWidth = localStorage.getItem(`${tableName.value}_${prop}_colWidth`);
        if (storageColWidth) {
          column.width = parseInt(storageColWidth) > 0 ? parseInt(storageColWidth) : column.width;
        } else {
          // 从表格列配置列表中获取列宽
          let configColWidth = tableColumnConfigs.value.find((item) => item.prop === prop)?.width;
          if (configColWidth) {
            column.width = configColWidth;
          }
        }
      }
    }
  };

  // 存储表格列宽
  const saveColumnWidth = (newWidth: number, oldWidth: number, column: TableColumnCtx<any>, event: MouseEvent) => {
    let prop = column.property;
    if (prop) {
      localStorage.setItem(`${tableName.value}_${prop}_colWidth`, newWidth.toString());
    }
  };

  // 重置列宽
  const resetColumnWidth = () => {
    let columns = tableRef.value?.store.states.columns.value;
    if (!columns || !Array.isArray(columns)) return;
    for (let column of columns) {
      let prop = column.property;
      if (prop) {
        // 删除本地存储的列宽数据
        localStorage.removeItem(`${tableName.value}_${prop}_colWidth`);
        // 从表格列配置列表中获取列宽
        let configColWidth = tableColumnConfigs.value.find((item) => item.prop === prop)?.width;
        if (configColWidth) {
          column.width = configColWidth;
        }
      }
    }
  };

  return {
    loadColumnWidth,
    saveColumnWidth,
    resetColumnWidth
  };
};

数据类型定义 interface/index.ts

import { ElTable } from "element-plus";

// ElTable 扩展实例类型,包含内部 store 属性
export type ElTableExtendedInstance = InstanceType<typeof ElTable> & {
  store: {
    states: {
      columns: {
        property?: string;
        // 其他列属性...
      }[];
    };
  };
};

// 表格列配置接口
export interface IColumnConfig {
  prop: string;
  label: string;
  width: number;
  [key: string]: any; // 允许其他属性
}


网站公告

今日签到

点亮在社区的每一天
去签到