el-table【合并行】+【筛选功能】+【配置列】+【点击跳转】功能

效果图:

 

1. 【合并行】

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

:span-method="objectSpanMethod"

spanNumArr: [], // 合并行数
posNum: [], // 记录位置


created() {
  // 获取合并行行数
  this.getSpanNumArr(this.tableData)
},

methods: {
  // 获取合并行的行数
  getSpanNumArr(data) {
    this.spanNumArr = []
    this.posNum = 0
    for (var i = 0; i < data.length; i++) {
      if (i === 0) {
        this.spanNumArr.push(1)
        this.posNum = 0
      } else {
        if (data[i].name === data[i - 1].name) {
          this.spanNumArr[this.posNum] += 1
          this.spanNumArr.push(0)
        } else {
          this.spanNumArr.push(1)
          this.posNum = i
        }
      }
    }
  },
  // 设置合并行
  objectSpanMethod({ row, column, rowIndex, columnIndex }) {
    if (column.property == 'name') {
      const _row = this.spanNumArr[rowIndex]
      const _col = _row > 0 ? 1 : 0 // 0 值是为了去除错位
      return {
        rowspan: _row,
        colspan: _col
      }
    }
  },
}

2.【筛选功能】

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

:filters="tableFilter[item.prop]"
:filter-method="filterHandler"

tableFilter: {}, // 定义过滤的值

created() {
  this.$nextTick(() => {
    // 初始化时将table的所有数据赋值给tableFilter,即默认展示所有数据
    this.handleFilter(this.tableData) 
  })
}

methods:{
     // 过滤选中的值
    filterHandler(value, row, column) {
      const property = column['property']
      
      // 过滤操作需要修改dom结构,因此需要用到 this.$nextTick
      this.$nextTick(() => {
        this.handleFilter(this.tableData, property) // 过滤完的列表数据,选中的属性
      })
      return row[property] === value // value是filters里绑定的数据里选中的项的value
    },
    // 过滤的方法
    handleFilter(list, property) {
      
      // 遍历展示列的每一列
      this.finallyColumns.forEach(val => {
        // 对每一列对应属性的值复制了一份且去重
        let arr = new Set(
          list.map(item => {
            return item[val.prop]
          })
        )
        
        // 将每一列的值格式化并放入到brr数组中
        let brr = []
        arr.forEach(item => {
          brr.push({ value: item, text: item })
        })
        
        // 初始化时:没有选中的属性,将所有的值添加到过滤的数组中
        if (property !== val.prop) {
          /**
           * this.$set( target, key, value)
           * target:表示数据源,即是你要操作的数组或者对象
           * key:要操作的的字段
           * value:更改的数据
           */
          this.$set(this.tableFilter, val.prop, brr)
        }
      })
    },
}

3. 【配置列】

tocheckList: [], // 标志是否勾选

<el-table-column prop="tag" label="操作" width="200" show-overflow-tooltip>
    <!--表头栏操作-->
    <template slot="header">
        操作
        <!-- 筛选框 -->
        <el-popover popper-class="popoverColumn" trigger="hover">
          <el-checkbox-group v-model="tocheckList">
            <el-checkbox
              v-for="(item, index) in tableColums"
              :key="item.id"
              :label="item.label"
            ></el-checkbox>
          </el-checkbox-group>
          <span slot="reference">
            <i class="el-icon-setting"></i>
          </span>
        </el-popover>
    </template>
    <el-button>删除</el-button>
</el-table-column>

created() {
    // 将列表的label赋值给【el-checkbox-group】绑定的tocheckList,即默认默认展示所有列
    this.tocheckList = this.tableColums.map(item => {
      return item.label
    })
},
methods: {
    // 过滤【el-checkbox-group】绑定的tocheckList中未选中的列并赋值给finallyColumns
    finallyColumns() {
      let finallyArray = []
      finallyArray = this.tableColums.filter(item =>
        this.tocheckList.includes(item.label)
      )
      return finallyArray
    }
}

4.【点击跳转】

<!-- 点击【姓名列】可以跳转 -->
<template slot-scope="{ row }">
    <el-link
        v-if="item.link"
        :key="index"
        :underline="false"
        style="color: #409eff"
        @click="handleClickRow(row, item)"
    >{{ row[item.prop] }}
    </el-link>
    <span v-else>{{ row[item.prop] }}</span>
</template>

methods: {
    // 点击链接可以实现跳转至详情页,这里简单化,只做了消息提示
    handleClickRow(row, item) {
      this.$message({
        message: '欢迎' + row.name,
        type: 'success'
      })
    }
}

下面附上完整代码:

<template>
  <div class="table">
    <el-table :data="tableData" ref="table" :span-method="objectSpanMethod" border>
      <el-table-column
        v-for="(item, index) in finallyColumns"
        sortable
        align="center"
        :key="item.id"
        :prop="item.prop"
        :label="item.label"
        :filters="tableFilter[item.prop]"
        :filter-method="filterHandler"
      >
        <!-- 点击【姓名列】可以跳转 -->
        <template slot-scope="{ row }">
          <el-link
            v-if="item.link"
            :key="index"
            :underline="false"
            style="color: #409eff"
            @click="handleClickRow(row, item)"
          >{{ row[item.prop] }}</el-link>
          <span v-else>{{ row[item.prop] }}</span>
        </template>
      </el-table-column>
      <el-table-column prop="tag" label="操作" width="200" show-overflow-tooltip>
        <!--表头栏操作-->
        <template slot="header">
          操作
          <!-- 筛选框 -->
          <el-popover popper-class="popoverColumn" trigger="hover">
            <el-checkbox-group v-model="tocheckList">
              <el-checkbox
                v-for="(item, index) in tableColums"
                :key="item.id"
                :label="item.label"
              ></el-checkbox>
            </el-checkbox-group>
            <span slot="reference">
              <i class="el-icon-setting"></i>
            </span>
          </el-popover>
        </template>
        <el-button>删除</el-button>
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
export default {
  name: 'Form',
  data() {
    return {
      // 表格数据
      tableData: [
        {
          id: 1,
          name: '张三',
          date: '2022-11-6',
          address: '上海市普陀区金沙江路 1516 弄上海市普陀区金沙江路',
          phone: '22',
          email: '11',
        },
        {
          id: 2,
          name: '李四',
          date: '2022-11-16',
          address: '上海市普陀区金沙江路 1516 弄上海市普陀区金沙江路',
          phone: '33',
          email: '11',
        },
        {
          id: 3,
          name: '张三',
          date: '2022-11-2',
          address: '上海市普陀区金沙江路 1516 弄上海市普陀区金沙江路',
          phone: '444',
          email: '11',
        },
        {
          id: 4,
          name: '张三',
          date: '2022-11-6',
          address: '上海市普陀区金沙江路 1516 弄上海市普陀区金沙江路',
          phone: '55',
          email: '11',
        },
        {
          id: 5,
          name: '张三',
          date: '2022-11-8',
          address: '上海市普陀区金沙江路 1516 弄上海市普陀区金沙江路',
          phone: '66',
          email: '111',
        },
        {
          id: 6,
          name: '张三',
          date: '2022-11-7',
          address: '上海市普陀区金沙江路 1516 弄上海市普陀区金沙江路',
          phone: '77',
          email: '112'
        }
      ],
      // 表头
      tableColums: [
        {
          prop: 'name',
          label: '姓名',
          width: '180',
          link: true
        },
        {
          prop: 'date',
          label: '日期',
          width: '180'
        },
        {
          prop: 'address',
          label: '地址',
          width: '180'
        },
        {
          prop: 'phone',
          label: '手机号码',
          width: '180'
        },
        {
          prop: 'email',
          label: '邮箱',
          width: '180'
        }
      ],
      tocheckList: [], // 标志是否勾选
      tableFilter: {}, // 定义过滤的值
      spanNumArr: [], // 合并行数
      posNum: [], // 记录位置
    }
  },
  created() {
    this.$nextTick(() => {
      // 初始化时将table的所有数据赋值给tableFilter,即默认展示所有数据
      this.handleFilter(this.tableData) 
    })
    // 将列表的label赋值给【el-checkbox-group】绑定的tocheckList,即默认默认展示所有列
    this.tocheckList = this.tableColums.map(item => {
      return item.label
    })
    // 获取合并行行数
    this.getSpanNumArr(this.tableData)
  },
  computed: {
    // 过滤【el-checkbox-group】绑定的tocheckList中未选中的列并赋值给finallyColumns
    finallyColumns() {
      let finallyArray = []
      finallyArray = this.tableColums.filter(item =>
        this.tocheckList.includes(item.label)
      )
      return finallyArray
    }
  },
  methods: {
    // 设置合并行
    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
      if (column.property == 'name') {
        const _row = this.spanNumArr[rowIndex]
        const _col = _row > 0 ? 1 : 0 // 0 值是为了去除错位
        return {
          rowspan: _row,
          colspan: _col
        }
      }
    },
    // 获取合并行的行数
    getSpanNumArr(data) {
      this.spanNumArr = []
      this.posNum = 0
      for (var i = 0; i < data.length; i++) {
        if (i === 0) {
          this.spanNumArr.push(1)
          this.posNum = 0
        } else {
          if (data[i].name === data[i - 1].name) {
            this.spanNumArr[this.posNum] += 1
            this.spanNumArr.push(0)
          } else {
            this.spanNumArr.push(1)
            this.posNum = i
          }
        }
      }
    },
    // 过滤选中的值
    filterHandler(value, row, column) {
      const property = column['property']
      
      // 过滤操作需要修改dom结构,因此需要用到 this.$nextTick
      this.$nextTick(() => {
        this.handleFilter(this.tableData, property) // 过滤完的列表数据,选中的属性
      })
      return row[property] === value // value是filters里绑定的数据里选中的项的value
    },
    // 过滤的方法
    handleFilter(list, property) {
      
      // 遍历展示列的每一列
      this.finallyColumns.forEach(val => {
        // 对每一列对应属性的值复制了一份且去重
        let arr = new Set(
          list.map(item => {
            return item[val.prop]
          })
        )
        
        // 将每一列的值格式化并放入到brr数组中
        let brr = []
        arr.forEach(item => {
          brr.push({ value: item, text: item })
        })
        
        // 初始化时:没有选中的属性,将所有的值添加到过滤的数组中
        if (property !== val.prop) {
          /**
           * this.$set( target, key, value)
           * target:表示数据源,即是你要操作的数组或者对象
           * key:要操作的的字段
           * value:更改的数据
           */
          this.$set(this.tableFilter, val.prop, brr)
        }
      })
    },
    // 点击链接可以实现跳转至详情页,这里简单化,只做了消息提示
    handleClickRow(row, item) {
      this.$message({
        message: '欢迎' + row.name,
        type: 'success'
      })
    }
  }
}
</script>

<style scoped>
h1 {
  text-align: center;
}
.table {
  width: 800px;
  display: inline-block;
  text-align: center;
  margin-left: 50%;
  transform: translate(-50%);
}
.el-checkbox-group {
  display: flex;
  flex-direction: column;
}
</style>

如有错误的地方,欢迎指正!文章来源地址https://uudwc.com/A/VNMvz

阅读剩余 89%

原文地址:https://blog.csdn.net/weixin_51317101/article/details/127992539

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请联系站长进行投诉反馈,一经查实,立即删除!

h
上一篇 2023年07月26日 19:47
Unity基础 音频组件以及音频播放
下一篇 2023年07月26日 19:48