element-ui框架 el-table组件如何能通过store.updateColumns方法更新表头列重绘显示?

element-ui框架 el-table组件如何能通过store.updateColumns更新表头列重绘显示,实现可配置切换显示不同列的效果

目前有一个已实现的案例,是将el-table源码复制到本地在页面中引用,通过$refs指向table实例调用其store.updateColumns()方法就能有效果,类似以下两种情况当前组件或层级嵌套组件都能触发:
this.$refs.commonTable.$refs.multipleTable.store.updateColumns(['field1']);
this.$refs.multipleTable.store.updateColumns(['field1']);

但是我自己尝试在页面中直接引用npm依赖中的el-table再调用updateColumns始终无法实现效果,单纯是静态demo,已排除异步和dom渲染更新等干扰因素,如下所示:

<el-table ref="commonTable">
  <el-table-column align="center" label='字段1' prop="field1" />
  <el-table-column align="center" label='字段2' prop="field2" />
  <el-table-column align="center" label='字段3' prop="field3" />
</el-table>

mounted() {
  this.$nextTick(() => {
    this.$refs.commonTable.store.updateColumns(['field1']);
  })
},

$refs指向在控制台都能正常获取打印出来,.store.updateColumns方法也是存在的,但就是没效果,换成源码table本地引用就好使,实在不明白为什么,难道就是因为引用方式的差异所导致吗?

阅读 315
avatarAI BotBETA

问题根源在于ElementUI的npm正式包和源码存在以下关键差异:

  1. 内部方法保护机制:
    npm包中的store对象经过封装处理,直接调用updateColumns可能无法触发响应式更新。而本地源码版本保留了完整的内部链路。
  2. 列状态同步缺失:
    需要手动维护列状态同步,推荐使用以下标准实现方案:
<template>
  <el-table 
    :data="tableData"
    :key="tableKey" // 强制刷新用
    ref="commonTable">
    <el-table-column 
      v-for="col in visibleColumns"
      :key="col.prop"
      :prop="col.prop"
      :label="col.label"
      v-show="col.visible"/>
  </el-table>
</template>

<script>
export default {
  data() {
    return {
      tableKey: 0,
      visibleColumns: [
        { prop: 'field1', label: '字段1', visible: true },
        { prop: 'field2', label: '字段2', visible: false },
        { prop: 'field3', label: '字段3', visible: false }
      ]
    }
  },
  methods: {
    toggleColumn(prop) {
      const column = this.visibleColumns.find(c => c.prop === prop)
      if (column) {
        column.visible = !column.visible
        this.tableKey++ // 强制表格重新渲染
      }
    }
  }
}
</script>
  1. 强制刷新备选方案(慎用):
    如果必须操作内部方法,需添加额外刷新逻辑:
updateColumns() {
  this.$refs.commonTable.store.updateColumns(newColumns)
  this.$nextTick(() => {
    this.$refs.commonTable.doLayout() // 强制重新布局
  })
}
  1. 版本差异验证:
    检查本地源码版本与npm版本是否一致(建议统一使用2.13.2+版本)

建议优先使用官方推荐的响应式方案,内部方法调用存在以下风险:

  • 版本升级兼容性问题
  • 不可预测的副作用
  • 响应式链路断裂
  • 多级嵌套表格时状态同步异常
2 个回答

可以这样处理:

store/config.js

const state = {
    tableHeader:  [] // 表头字段
};

const mutations = {
    SET_TABLE_HEADER(state, value) {
        state.tableHeader = value;
    }
};

const actions = {};

export default {
    namespaced: true,
    state,
    mutations,
    actions,
};

组件

import { mapState } from 'vuex';


computed: {
    ...mapState({
        tableHeader: (state) => state.config.tableHeader,
    }),
}

this.$store.commit('config/SET_TABLE_HEADER', ['需要配置的表头'])


<el-table ref="commonTable">
  <el-table-column
        v-for="(filed, index) in tableHeader"
        :key="index"
        align="center"
        label='字段1'
        :prop="filed"
    />
</el-table>



mounted() {
  this.$nextTick(() => {
    setTimeout(() => {  
      const columns = this.$refs.commonTable.store.states.columns.filter(col => 
        col.property === 'field1'
      );
      this.$refs.commonTable.store.states.columns = columns;
      this.$refs.commonTable.doLayout();
    }, 0);
  });
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏