Element-plus Table组件实现单选/多选切换+二次封装

936 阅读2分钟

项目需求需要将el-table封装成单多选切换,于是就自己封装了一下,不仅实现了单多选切换功能,且二次封装后增加了开发效率。

技术选用

  • vue3
  • element-plus

成品展示

2222.gif

单多选功能实现

表格选择项变动会触发该组件,当组件收到的props.chooseSingle传参为true时,单选开启。其中,val为一个动态数组,里面装了所有选中项,最新选中项在数组最后,所以当组件为单选状态时,我们只需要保留val中最新元素,即val[val.length-1]

const handleSelectionChange = (val) => {
  if (props.chooseSinge) {
    const temp = val.slice(0, val.length-1);
    temp.forEach((el) => {
        nextTick(() => {
          multipleTableRef.value.toggleRowSelection(el, false);
        });
    });
    val.splice(0, val.length-1);
  }
  multipleSelection.value = val
}

封装之后的完整代码

代码结构:

image.png

思路:

  • 一个config.js文件控制表头参数
  • PageTable表格通用组件
  • 父组件向PageTable传递表头信息参数List,填充表格内容tableData,同时传递参数chooseSinge控制表格单多选

父组件引用表格子组件 ParentCom.vue

父组件通过chooseSingechangeMode函数控制单多选切换

<template>
  <PageTable :chooseSinge="chooseSinge" @changeMode="changeMode" :list="List" :tableData="tableData"/>
</template>

<script setup>
import PageTable from './components/PageTable.vue'
import {List} from './components/listConfig'
import {ref} from 'vue'
const chooseSinge = ref(true)
function changeMode() {
  chooseSinge.value = !chooseSinge.value
}
const tableData = [
  {
    label: '03',
    sum: '22',
    modify: '5',
  },
  {
    label: '02',
    sum: '33',
    modify: '23',
  },
  {
    label: '04',
    sum: '44',
    modify: '5',
  },
  {
    label: '01',
    sum: '55',
    modify: '3',
  },
  {
    label: '08',
    sum: '66',
    modify: '4',
  },
  {
    label: '06',
    sum: '77',
    modify: '0',
  },
  {
    label: '07',
    sum: '88',
    modify: '1',
  },
]
</script>

表头参数设置

listConfig.js文件

export const List = {
    propList: [
      {prop: 'label', label: '标签', width: '120'},
      {prop: 'sum', label: '总量', width: '120'},
      {prop: 'modify', label: '修改量', width: '120'},
    ],
  }

表格部分

表格为子组件,这里单多选的切换由父组件传递Boolean类型的参数来控制。

运用v-bind='item'将item对象中的prop、label等属性绑定到el-table-column组件的属性上渲染出对应的表格列。

:row属性是将当前行的数据对象scope.row绑定到插槽的属性row上,将scope.row[item.prop]动态绑定到插槽内部的文本内容上,从而实现了根据数据动态渲染表格列的功能。

<template>
  <el-table
    ref="multipleTableRef"
    :data="tableData"
    style="width: 500px"
    @selection-change="handleSelectionChange"
  >
    <el-table-column
      align="center"
      type="selection"
      width="60">
    </el-table-column>
    // 表头信息填入
    <template v-for="item in list.propList" :key="item.lable">
      <el-table-column v-bind="item" show-overflow-tooltip>
      //表格内容填充
        <template #defalut="scope">
           <slot :row="scope.row">
            {{ scope.row[item.prop] }}
          </slot>
        </template>
      </el-table-column>
    </template>
  </el-table>
  <div style="margin-top: 20px">
    <el-button @click="changeMode"
      >{{ props.chooseSinge? '单选':'多选' }}</el-button
    >
    <el-button @click="toggleSelection">清除</el-button>
  </div>
    
</template>

<script setup>
import { ElTable } from 'element-plus';
import {ref, nextTick, defineProps, defineEmits} from 'vue'
const props = defineProps({
    chooseSinge: {
      type: Boolean,
      defalut: false
    },
    list: {
      require: true
    },
    tableData: {
      require: true
    }
  }
)
const emit = defineEmits(
  ['changeMode']
)


const multipleTableRef = ref()
const multipleSelection = ref([])
// 表格选项变动会触发该函数
const handleSelectionChange = (val) => {
  if (props.chooseSinge) {
    const temp = val.slice(0, val.length-1);
    temp.forEach((el) => {
        nextTick(() => {
          multipleTableRef.value.toggleRowSelection(el, false);
        });
    });
    val.splice(0, val.length-1);
  }
  multipleSelection.value = val
}
// 清空选项
const toggleSelection = () => {
  multipleTableRef.value.clearSelection()
  
}
// 单多选切换
const changeMode = () => {
  emit('changeMode') // 触发父组件changeMode函数
  multipleTableRef.value.clearSelection()
}
</script>