vue el-table implementa un encabezado dinámico

I. Introducción

Como todos sabemos, hay un componente de tabla el-table en element-ui, que se utiliza para mostrar múltiples datos con una estructura similar. Anteriormente encontré la necesidad de controlar manualmente la visualización del encabezado de el-table. Es decir, si la tabla tiene un total de 10 columnas de datos, puede decidir cuántas columnas mostrar configurando la casilla de verificación.

2. Código

En aras de la reutilización del código, la página de configuración se extrae en componentes separados, por lo que se pasarán valores entre los componentes del código
Componente principal (página de tabla)

<template>
  <div class="testTable">
    <div class="settingIcon">
      <i class="el-icon-setting" @click="showSetting" />
    </div>
    <el-table :data="tableData" style="width: 100%">
      <el-table-column
        v-for="item in showTableColumn"
        :key="item.prop"
        :fixed="item.fixed"
        :align="item.align"
        :prop="item.prop"
        :min-width="item.minWidth"
        :width="item.width"
        :show-overflow-tooltip="item.tooltip"
        :resizable="item.resizable"
        :label="item.label"
      />
    </el-table>
    <!-- 配置页面 -->
    <key-setting
      :visible.sync="isSetting"
      :data-arr="AllPropertyArrForManage"
      :check-list="checkProp"
      :default-arr="DefaultPropertyArrForManage"
      @confirm="handleConfirm"
    />
  </div>
</template>

<script>
import keySetting from '@/components/keySetting/index.vue'
export default {
    
    
  components: {
    
     keySetting },
  data() {
    
    
    return {
    
    
      showTableColumn: [],
      tableData: [
        {
    
    
          date: '2016-05-02',
          age: '28',
          gender: '男',
          name: '王虎',
          address: '上海市普陀区金沙江路 1518 弄'
        },
        {
    
    
          date: '2016-05-04',
          age: '20',
          gender: '男',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1517 弄'
        },
        {
    
    
          date: '2016-05-01',
          age: '25',
          gender: '男',
          name: '王二虎',
          address: '上海市普陀区金沙江路 1519 弄'
        },
        {
    
    
          date: '2016-05-03',
          age: '40',
          gender: '男',
          name: '王大虎',
          address: '上海市普陀区金沙江路 1516 弄'
        }
      ],
      isSetting: false,
      AllPropertyArrForManage: [
        {
    
     prop: 'date', label: '日期', minWidth: '120',
          align: 'center',
          tooltip: true,
          resizable: true },
        {
    
     prop: 'age', label: '年龄', minWidth: '120',
          align: 'center',
          tooltip: true,
          resizable: true },
        {
    
     prop: 'gender', label: '性别', minWidth: '120',
          align: 'center',
          tooltip: true,
          resizable: true },
        {
    
     prop: 'name', label: '姓名', minWidth: '120',
          align: 'center',
          tooltip: true,
          resizable: true },
        {
    
     prop: 'address', label: '地址', minWidth: '120',
          align: 'center',
          tooltip: true,
          resizable: true }
      ], // 所有字段
      checkProp: [], // 选中字段
      DefaultPropertyArrForManage: [
        'name', 'age'
      ] // 默认选中字段
    }
  },
  mounted() {
    
    
    this.dealTableColumn(this.checkProp)
  },
  methods: {
    
    
  // 点击配置图标
    showSetting() {
    
    
      this.isSetting = !this.isSetting
      if (this.isSetting) {
    
    
        this.checkProp = this.DefaultPropertyArrForManage
      }
    },
    // 提交确定事件 实际工作中会调接口
    handleConfirm(val) {
    
    
      this.checkProp = val
      this.dealTableColumn(this.checkProp)
    },
    // 重新渲染table表格
    dealTableColumn(arr) {
    
    
      this.showTableColumn = []
      this.AllPropertyArrForManage.forEach((item) => {
    
    
        if (arr.indexOf(item.prop) > -1) {
    
    
          this.showTableColumn.push(item)
        }
      })
    }
  }
}
</script>

Subcomponentes (página de configuración)

<template>
  <div class="wrapper">
    <el-card class="box-card" :style="{'width': visible ? '230px' : '0', 'opacity': visible ? '1' : '0'}">
      <div slot="header" style="min-width: 200px">
        <span>字段配置</span>
        <span class="fr close-btn" @click="$emit('update:visible', false)">×</span>
      </div>
      <div>
        <el-checkbox v-model="checkAll" label="a" :indeterminate="isIndeterminate" @change="selectAll">全选</el-checkbox>
        <el-checkbox-group v-model="realList" class="check-list" @change="handleCheckedChange">
          <el-checkbox v-for="item in dataArr" :key="item.prop" :label="item.prop" :disabled="item.prop=='name'">{
    
    {
    
     item.label }}</el-checkbox>
        </el-checkbox-group>
      </div>
      <div class="footer" style="min-width: 200px">
        <el-button type="primary" size="small" :disabled="realList.length < 1" @click="confirm">确定</el-button>
        <el-button size="small" @click="reset">重置</el-button>
        <el-button size="small" @click="cancel">取消</el-button>
      </div>
    </el-card>
  </div>
</template>

<script>
export default {
    
    
  name: 'KeySetting',
  props: {
    
    
    visible: {
    
    
      type: Boolean,
      default: false
    },
    dataArr: {
    
    
      type: Array,
      default: () => []
    },
    checkList: {
    
    
      type: Array,
      default: () => []
    },
    defaultArr: {
    
    
      type: Array,
      default: () => []
    }
  },
  data() {
    
    
    return {
    
    
      checkAll: false,
      realList: [],
      isIndeterminate: true
    }
  },
  watch: {
    
    
    checkList(val) {
    
    
      this.realList = val
      if (val.length === this.dataArr.length) {
    
    
        this.isIndeterminate = false
        this.checkAll = true
      }
    }
  },
  methods: {
    
    
  // 全选按钮
    selectAll(val) {
    
    
      this.realList = val ? this.dataArr.map(item => item.prop) : this.defaultArr
      if (val) {
    
    
        this.isIndeterminate = false
      } else {
    
    
        this.isIndeterminate = true
      }
    },
    // el-checkbox选中事件
    handleCheckedChange(value) {
    
    
      const checkedCount = value.length
      this.checkAll = checkedCount === this.dataArr.length
      this.isIndeterminate = checkedCount > 0 && checkedCount < this.dataArr.length
    },
    // 点击确定
    confirm() {
    
    
      this.$emit('confirm', this.realList)
      this.$emit('update:visible', false)
    },
    // 点击重置
    reset() {
    
    
      this.realList = [...this.defaultArr]
      this.isIndeterminate = true
      this.checkAll = false
    },
    // 点击取消
    cancel() {
    
    
      this.realList = this.checkList
      this.$emit('update:visible', false)
    }
  }
}
</script>

El código anterior no incluye estilos CSS, puede agregarlos según la situación real.

3. El efecto es el siguiente.

1. Página normal: todos los datos de la columna
Insertar descripción de la imagen aquí
2. Página de configuración
Insertar descripción de la imagen aquí
3. Configuración dinámica
Insertar descripción de la imagen aquí

4. Otros

Los datos demostrados en el código anterior son fijos. En el trabajo real, habrá soporte de interfaz de back-end, por lo que la actualización de datos será muy conveniente.
¡Bienvenido como referencia!

Supongo que te gusta

Origin blog.csdn.net/qq_45093219/article/details/127122803
Recomendado
Clasificación