一、自定义表格表头

在开发过程中,会遇到需要在表头添加图标样式的场景,通过slot可以实现添加表头样式。

<template>
  <el-table
    :data="tableData"
    style="width: 100%">
    <el-table-column v-for="(item, i) in header" :prop="item.column" :label="item.label">
       <template v-slot:header>
        <div class="column">
          <span>{{item.label}}</span>
          <i class="el-icon-arrow-down"></i>
         </div>
      </template>
    </el-table-column>
  </el-table>
</template>

<script>
  export default {
    data() {
      return {
        tableData: [{
          date: '2016-05-02',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1518 弄'
        }, {
          date: '2016-05-04',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1517 弄'
        }, {
          date: '2016-05-01',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1519 弄'
        }, {
          date: '2016-05-03',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1516 弄'
        }],
        header: [{
          column: 'date',
          label: '时间'
        }, {
          column: 'name',
          label: '姓名'
        }, {
          column: 'address',
          label: '日期'
        }],
        search: ''
      }
    },
    methods: {
      handleEdit(index, row) {
        console.log(index, row);
      },
      handleDelete(index, row) {
        console.log(index, row);
      }
    },
  }
</script>

实现效果:

二、表格右侧固定

循环遍历表格时,不能单独给列添加固定属性fixed,因此可以通过prop结合fixed来设置。

fixed:列是否固定在左侧或者右侧,true 表示固定在左侧,false 则表示不固定
fixed:可选值 true, left, right

<el-table-column v-for="(item, i) in header" :prop="item.column" :label="item.label" :fixed="item.column === 'date' ? true : false" :min-width="100">
       <template v-slot:header>
        <div class="column">
          <span>{{item.label}}</span>
          <i class="el-icon-arrow-down"></i>
         </div>
      </template>
    </el-table-column>

效果截图:

三、表格表头筛选功能

table在列中设置filtersfilter-method属性即可开启该列的筛选,filters 是一个数组,filter-method是一个方法,它用于决定某些数据是否显示,会传入三个参数:value, row 和 column

<el-table-column
  prop="date"
  label="日期"
  sortable
  width="180"
  column-key="date"
  :filters="[{text: '2016-05-01', value: '2016-05-01'}, {text: '2016-05-02', value: '2016-05-02'}, {text: '2016-05-03', value: '2016-05-03'}, {text: '2016-05-04', value: '2016-05-04'}]"
  :filter-method="filterHandler"
>
</el-table-column>

filterHandler(value, row, column) {
  const property = column['property'];
  return row[property] === value;
}

通过设置filters来筛选数据,filter-method方法将筛选的值过滤处理。

但是在业务场景里面,目前table值提供了重置确认两种筛选功能,如果需要数据量过于庞大,则需要添加模糊查询,因此需要自定义筛选组件。

1、定义搜索框

<div style="width: 150px">
  <el-input
    placeholder="请输入内容"
    prefix-icon="el-icon-search"
    v-model="input2">
  </el-input>
</div>

2、定义多选框

<template>
  <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange">全选</el-checkbox>
  <div style="margin: 15px 0;"></div>
  <el-checkbox-group v-model="checkedCities" @change="handleCheckedCitiesChange">
    <el-checkbox v-for="city in cities" :label="city" :key="city">{{city}}</el-checkbox>
  </el-checkbox-group>
</template>
<script>
  const cityOptions = [
  {text: '上海', value: '1'},
  {text: '北京', value: '2'},
  {text: '北京', value: '3'},
  {text: '深圳', value: '4'},
  {text: '杭州', value: '5'}];
  export default {
    data() {
      return {
        checkAll: false,
        // 选中的数据
        checkedCities: ['1', '2'],
        cities: cityOptions,
        isIndeterminate: true
      };
    },
    methods: {
      handleCheckAllChange(val) {
        const checked = this.cities.map(o => o.value)
        this.checkedCities = val ? checked : [];
        this.isIndeterminate = false;
      },
      handleCheckedCitiesChange(value) {
        let checkedCount = value.length;
        this.checkAll = checkedCount === this.cities.length;
        this.isIndeterminate = checkedCount > 0 && checkedCount < this.cities.length;
      }
    }
  };
</script>

效果截图:

四、table列表多选框

Table-column

type:对应列的类型。如果设置了 selection 则显示多选框;如果设置了 index 则显示该行的索引(从 1 开始计算);如果设置了 expand 则显示为一个可展开的按钮

HTML:

<el-table
  :data="tableData"
  style="width: 100%">
  <el-table-column v-for="(item, i) in header" :prop="item.column" :label="item.label">
     <template v-slot:header>
      <div class="column">
        <span>{{item.label}}</span>
        <i class="el-icon-arrow-down"></i>
       </div>
    </template>
    <template slot-scope="{row, column, $index}">
      <div class="box" v-if="item.column === 'isCheck'">
        <el-checkbox v-model="row.isCheck"></el-checkbox>
       </div>
      <div class="text" v-else>
        <span>{{ row[item.column] }}</span>
       </div>
    </template>
  </el-table-column>
</el-table>

JS代码:

// js
data() {
  return {
    tableData: [{
      date: '2016-05-02',
      name: '王小虎',
      address: '上海市普陀区金沙江路 1518 弄',
      isCheck: false
    }, {
      date: '2016-05-04',
      name: '王小虎',
      address: '上海市普陀区金沙江路 1517 弄',
      isCheck: false
    }, {
      date: '2016-05-01',
      name: '王小虎',
      address: '上海市普陀区金沙江路 1519 弄',
      isCheck: false
    }, {
      date: '2016-05-03',
      name: '王小虎',
      address: '上海市普陀区金沙江路 1516 弄',
      isCheck: false
    }],
    header: [{
      column: 'date',
      label: '时间'
    }, {
      column: 'name',
      label: '姓名'
    }, {
      column: 'address',
      label: '日期'
    }, {
      column: 'isCheck',
      label: '是否选择'
    }]
  }
}

实现效果:

五、table合并表头、行列

1、合并表头

通过给table传入header-cell-style方法,表头单元格的 style 的回调方法,也可以使用一个固定的 Object 为所有表头单元格设置一样的 Style。

Function({row, column, rowIndex, columnIndex})/Object

内容:实现第一列和第二列表头合并

html

<el-table
  :data="tableData"
  style="width: 100%"
  :header-row-style="headMerge">
  <el-table-column
    prop="date"
    label="日期"
    width="180">
  </el-table-column>
  <el-table-column
    prop="name"
    label="姓名"
    width="180">
  </el-table-column>
  <el-table-column
    prop="address"
    label="地址">
  </el-table-column>
</el-table>

方法一:

js

// js
methods: {
  headMerge({row, column, rowIndex, columnIndex}) {
    if(rowIndex===0 && columnIndex===0) {
      this.$nextTick(()=> {
        if(document.getElementsByClassName(column.id).length!==0) {
          document.getElementsByClassName(column.id)[0].setAttribute('colSpan',2);
          return false
        }
      })
      return column
    }
    //if(rowIndex===1 && (columnIndex===0 || columnIndex===1)) {
     // return {display:'none'}
    //}

  }
}

方法二:

js

methods: {
  setColSpan() {
    // console.log(document.getElementsByClassName("el-table__header"))
    // 获取表头的所有单元格
    var x = document.getElementsByClassName("el-table__header")[0].rows[0].cells
    // 将第二列表头单元格的colSpan设为2
    x[1].colSpan = 2
    // 将第三列表头单元格的display设为none
    x[2].style.display = 'none'
  }
},
mounted() {
    this.$nextTick(() => {
      this.setColSpan();
    })
}

实现效果:

2、合并行列

通过给table传入span-method方法可以实现合并行或列,方法的参数是一个对象,里面包含当前行row、当前列column、当前行号rowIndex、当前列号columnIndex四个属性。该函数可以返回一个包含两个元素的数组,第一个元素代表rowspan,第二个元素代表colspan。 也可以返回一个键名为rowspan和colspan的对象。

function ({ row, column, rowIndex, columnIndex })

js

// :span-method="objectSpanMethod"

mounted() {
  // 合并列为name
  this.getSpanArr(data, 'name')
},

methods: {
  objectSpanMethod({ row, column, rowIndex, columnIndex }) {
    // 第一列单元格合并
    if (columnIndex === 0) {
      const _row = this.spanArr[rowIndex]
      const _col = _row > 0 ? 1 : 0

      return {
         rowspan: _row,
         colspan: _col
      }
    }
  },
  getSpanArr(data, key) {
    this.spanArr = []
    this.pos = ''
    for(let i = 0; i < data.length; i++) {
      if (i === 0) {
         this.spanArr.push(1)
         this.pos = 0
      } else {
        if (data[i][key] === data[i-1][key]) {
          this.spanArr[this.pos] += 1
          this.spanArr.push(0)
        } else {
          this.spanArr.push(1)
          this.pos = i
        }
      }
    }
  }
}

效果截图

2、合并多行多列

js

data() {
   return {
      // 需要合并的列
      mergeColumn: ['date', 'name'],
      spanArr: {}
   }
},
mounted() {
  this.spanArr = this.getSpanArr(this.tableData)
},
methods: {
  objectSpanMethod({ row, column, rowIndex, columnIndex }) {
    for(let i = 0; i < this.mergeColumn.length; i++) {
      if(column.property == this.mergeColumn[i]) {
        return {
          rowspan: this.spanArr[this.mergeColumn[i]][rowIndex],
          colspan: this.spanArr[this.mergeColumn[i]][rowIndex] > 0 ? 1 : 0
        }
      }
   }
  },
  getSpanArr(data) {
    let obj = {}
    for(let j = 0; j < this.mergeColumn.length; j++) {
      let arr = []
      let ind = 0
      for(let i = 0; i < data.length; i++) {
        if(i === 0) {
          arr.push(1)
        } else {
          if(data[i][this.mergeColumn[j]] == data[i-1][this.mergeColumn[j]]){
            arr[ind] += 1
            arr.push(0)
          }else {
            arr.push(1)
            ind = i
          }
        }
      }
      obj[this.mergeColumn[j]] = arr
      }
      return obj

    }
  }
}

效果截图

结语

成熟的标志,是遇到事,不会沉浸自伶,而是第一时间解决当下的问题。


羽玉
10 声望0 粉丝