Vue3+elementPlus:el-table列设置-动态展示列 (一)

3,380 阅读2分钟

列设置功能

1.动态设置列是否展示 (本篇内容)

2.可拖拽设置列的显示顺序(juejin.cn/post/735837…)

image.png

思路

elementplus官方文档:element-plus.org/zh-CN/compo…

列,我们可以动态生成,结合el-checkbox的基础用法,创建一个数组,包含生成列的所需元素和一个控制显示状态的元素。

// 表格列内容
const columnList=ref([{
  prop:'name',
  label:'姓名',
  ifcolumn:true,
},
{
  prop:'phone',
  label:'手机号',
  ifcolumn:true,
}
])
//动态渲染表格
  <el-table
        stripe
        :data="list"
        style="width: 100%"
        :cell-style="{ textAlign: 'center' }"
        :header-cell-style="{
          'text-align': 'center',
          background: '#ebeef5',
          'font-size': '15px',
        }"
      >
        <el-table-column type="index" label="序列号" width="80px" />
        
        <!--重点-->
        <template v-for="(item,index) in columnList" :key="index"   >
          <el-table-column v-if="item.ifcolumn" :label="item.label" :prop="item.prop" />
        </template>
       
        <el-table-column fixed="right" label="操作">
          <template #default="scope">
            <el-button
              link
              type="primary"
              size="small"
              @click="goTrain(scope.row)"
              >查看记录</el-button
            >
          </template>
        </el-table-column>
      </el-table>

这样我们动态生成的列,就可以通过el-checkbox 绑定数组的ifcolumn,来控制列的展示。

//html
 <template #content>
        <div class="s-head">
          <div class="name">
            <el-checkbox
              v-model="checkAll"
              :indeterminate="isIndeterminate" //控制是否全选中间状态
              @change="handleCheckAllChange"//全选
              >列展示</el-checkbox
            >
          </div>
        </div>
        <div class="s-content">
          <div
            class="item"
            id="item"
            ref="tableRef"
            v-for="(res, i) in row.columnList"
            :key="res.prop"
          >
            <template>
              <el-icon :size="15" class="rank" :key="i"><Rank /></el-icon>
              <el-checkbox
                :label="res.label"
                v-model="res.ifcolumn"//绑定数组的ifcolumn
                @change="CheckedChange"
                >{{ res.label }}</el-checkbox
              >
            </template>
          </div>
        </div>
      </template>

完整代码

项目中多个页面都使用到了列设置,这里就封装成组件使用

index.vue

<script setup>
...省略一些引入
//列设置
// 表格列内容
const columnList=ref([{
  prop:'name',
  label:'姓名',
  ifcolumn:true,
},
{
  prop:'phone',
  label:'手机号',
  ifcolumn:true,
}
])

// 列设置赋值
const getlistValue=(val)=>{
  columnList.value=val
}


//表格内容
const list = [
  {
    name: "张三",
    phone:'13012345678'
  },
];
</script>

<template>
 <!--表格-->
    <div class="list">
      <div class="table-tools">
        <div class="settings">
          <ColsettingVue
          :columnList="columnList"
          @getlistValue="getlistValue"
          />  
        </div>
        <el-button type="success" class="addButton">添加</el-button>
      </div>

      <el-table
        stripe
        :data="list"
        style="width: 100%"
        :cell-style="{ textAlign: 'center' }"
        :header-cell-style="{
          'text-align': 'center',
          background: '#ebeef5',
          'font-size': '15px',
        }"
      >
        <el-table-column type="index" label="序列号" width="80px" />
        
        <template v-for="(item,index) in columnList" :key="index"   >
          <el-table-column v-if="item.ifcolumn" :label="item.label" :prop="item.prop" />
        </template>
       
        <el-table-column fixed="right" label="操作">
          <template #default="scope">
            <el-button
              link
              type="primary"
              size="small" 
              >查看记录</el-button
            >
          </template>
        </el-table-column>
      </el-table>
    </div>
</template>

<style>
 .list {
    .table-tools {
      display: flex;
      justify-content: space-between;
      flex-direction: row-reverse;
      align-items: center;
    }

    .settings {
      color: #999;
      cursor: pointer;
      font-size: 18px;
      position: relative;

      :deep(.el-popper .is-light) {
        transform: (1380px 343px);
      }
    }
  }
  </style>

组件Colsetting.vue

<script setup>
import { computed, onMounted, ref } from "vue";

//列设置
const visible = ref(false);
const checkAll = ref(false);
const isIndeterminate = ref(true);

// 接收父组件
const row = defineProps({
  columnList: Array,
});

const emits=defineEmits(["getlistValue"])

const list =ref(row.columnList) ;

// 全选按钮
const handleCheckAllChange = (val) => {
  list.value.forEach((e) => {
    e.ifcolumn = val;
  });
  emits("getlistValue",list.value)
};
const CheckedChange = () => {
  // 判断是否全选
  let checkall = true;
  list.value.forEach((e) => {
    if (e.ifcolumn == false) {
      return (checkall = false);
    }
  });
  checkAll.value = checkall;
  isIndeterminate.value = !checkall;
  emits("getlistValue",list.value)
};
</script>

<template>
  <div>
    <el-tooltip :visible="visible" placement="bottom-end" effect="light">
      <template #content>
        <div class="s-head">
          <div class="name">
            <el-checkbox
              v-model="checkAll"
              :indeterminate="isIndeterminate"
              @change="handleCheckAllChange"
              >列展示</el-checkbox
            >
          </div>
        </div>
        <div class="s-content">
          <div
            class="item"
            id="item"
            ref="tableRef"
            v-for="(res, i) in list"
            :key="res.prop"
          >
              <el-icon :size="15" class="rank" :key="i"><Rank /></el-icon>
              <el-checkbox
                :label="res.label"
                v-model="res.ifcolumn"
                @change="CheckedChange"
                >{{ res.label }}</el-checkbox
              >
          </div>
        </div>
      </template>
      <el-button  @click="visible = !visible">
      <el-icon><Setting /></el-icon>
      </el-button>
    </el-tooltip>
  </div>
</template>

<style scoped lang="scss">
.s-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px solid #dedede;

  .rest {
    color: var(--el-color-primary);
    cursor: pointer;
  }
}

.s-content {
  width: 150px;
  .item {
    display: flex;
    align-items: center;
  }
}

.rank {
  margin: 8.5px 5px;
}
</style>

这样动态展示列的功能就完成了!!

补充

若使用该组件时发现,同个页面的下拉框除谷歌浏览器以外都点不开,那就在el-tooltip展示按钮处添加el-button

<template>
  <div>
    <el-tooltip :visible="visible" placement="bottom-end" effect="light">
      <template #content>
        <div class="s-head">
          ...
        </div>
      </template>
      
      <!--重点-->
      <!--错误-->
       <!--<el-icon @click="visible = !visible"><Setting /></el-icon>--> 
      
      <!--正确-->
       <el-button @click="visible = !visible">
        <el-icon><Setting /></el-icon>
      </el-button>
      
      
    </el-tooltip>
  </div>
</template>