背景

        刚开始为了写表格方便所以在使用element时候使用v-for循环来写,所以代码类似于如下

<el-table-column
        v-for="(item, index) in tableHeads"
        :key="index"
        :label="item.label"
        :prop="item.prop"
        :width="item.width"
        align="center"
        show-overflow-tooltip>
        <template slot-scope="scope" >
            <div v-if="item.label== '操作'">
                <el-button @click="editOn(scope.row,'edit')">编辑</el-button>
            </div>
            <span v-else>{{scope.row[item.prop]}}</span>
        </template>
</el-table-column>

        这样写以后加条目就只需要在data里加就行,不用写一长串样式,而且有什么条目有特殊需求用插槽就行,show-overflow-tooltip这个是为了防止某个字段太长,本来按钮这些加了也没什么,直到使用若依框架后,xxx看到了若依里有显隐列,要求我们每一个表格都加上。

修改

        顾客是上帝,所以就开始使用若依的源码进行适配,若依表格右上工具栏源码地址:

  改是简单的,只要在el-table-column的循环里加一个v-if="item.visible",data里面的表格头部加上对象{key: 0,visible: true,}(注:key是整数递增的,visible都是true,除非一开始就要隐藏某一列),传给若依框架的columns(注:不是重点,只是dialog里选择的数据,可以把表格列赋值给columns,只要有key和visible就行,例:

/**
*    html里的
*/
<el-table-column
        v-for="(item, index) in tableHeads"
        :key="index"
        v-if="item.visible"
        :label="item.label"
        :prop="item.prop"
        :width="item.width" 
        align="center"
        show-overflow-tooltip>
</el-table-column>
/**
*    data(){return{}}里的
*/
// 表格的表头,列
tables: {
        heads: [
          {
            label: "序号",
            prop: "id",
            width: "",
            key: 1,
            visible: true,
          },
}
// 若依框架的column
ModulesDatas: {
        // 添加按钮
        adds: false,
        // 上传按钮
        uploads: false,
        // 下载按钮
        downloads: false,
        columns: []
}
/**
*    mounted里的
*/
// 在mounted赋值给若依框架的column
this.ModulesDatas.columns = this.tables.heads

),我这里是两个组件里的内容,虽然v-if与v-for在一起不太好,但是现在也没什么办法,起码能运行就不算错。

测试

        测试开始就发现布局有问题,尤其是涉及到按钮(el-button)、状态(el-tag)等非纯文本的,都会或多或少的在切换列的显隐产生错位。

错误情况

elementuitable隐藏列 el table column 隐藏_javascript

elementuitable隐藏列 el table column 隐藏_elementuitable隐藏列_02

 正常情况

elementuitable隐藏列 el table column 隐藏_elementuitable隐藏列_03

        刚开始以为是渲染问题,所以重新渲染table就行,虽然嵌套的厉害,但是两个ref解决,先修改若依框架进行强制渲染,在监听变化的时候进行刷新

// 右侧列表元素变化
    dataChange(data) {
      for (let item in this.columns) {
        const key = this.columns[item].key;
        this.columns[item].visible = !data.includes(key);
      }
    // 刷新
      this.$nextTick(()=>{
        this.$forceUpdate()
        this.$emit('change')
      })
    },
<!-- 由于按钮和表格是两个不同的组件,所以两次ref -->
<rightButton
      @toolbarOn="toolbarOn"
      :ModulesDatas="ModulesDatas"
      @change="$refs.Table.$refs.multipleTable.doLayout()"
      ref="modulesBtns">
</rightButton>

        但是这样渲染并没有成功,于是问了大佬,最后发现问题出在show-overflow-tooltip,表头比如定宽130px,但是在显隐列的时候tooltip总是变化长度,所以只要表格除纯文本不要show-overflow-tooltip就行。

解决

a==b?true:false类似的式子即可

:show-overflow-tooltip="item.prop!='edit'?true:false"

问题

        虽然解决了,但是继续测试发现不论式子是item.prop!='edit'?true:false还是item.prop=='edit'?true:false都是正确的,不过不打算继续深究了,反正跑起来了

追加

        1.普通文本基本不受影响,但是如果是时间文本或者el-button的type=text,就会受到影响,基础办法依然是三元式处理,最简单,例:

:show-overflow-tooltip="item.label=='操作'||item.label=='状态'?false:true"

但是这样子只不过是一种妥协,还是在插槽里用el-tooltip最好,基本不会受到影响,而且按钮这些最好还是别用el-tooltip,我现在也只有普通文本和tag标签才使用,例:

<el-tooltip v-else :content="scope.row[item.prop]" placement="top">
            <span >{{ scope.row[item.prop] }}</span>
          </el-tooltip>
<!-- 单据状态 -->
          <span v-if="item.prop == 'deviceCode' ">
            <el-tooltip :content="scope.row.deviceCode" placement="top" effect="dark">
              <el-tag  @click="deviceCodeOn(scope.row)">
                <span v-text="scope.row.deviceCode"></span>
              </el-tag>
            </el-tooltip>
          </span>

如果还有问题,试试以下方法        

2.再次追加解决方法:是因为封装组件的时候一部分列没有固定宽度,所以在v-if隐藏的时候就会随时变化

        解决方法1:将所有的列都设置固定宽度,这样虽然不会乱序渲染失误,但是表格也不能随之变化也就是电脑可能有1920px,但是你表格只占600px

        解决方法2:所有列除了操作列(或者其他任意一列)都没有宽度,只有一列有固定宽度,这样只要操作不是单独的一列,那么表格宽度是可变化的