项目需求需要将el-table封装成单多选切换,于是就自己封装了一下,不仅实现了单多选切换功能,且二次封装后增加了开发效率。
技术选用
- vue3
- element-plus
成品展示
单多选功能实现
表格选择项变动会触发该组件,当组件收到的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
}
封装之后的完整代码
代码结构:
思路:
- 一个config.js文件控制表头参数
- PageTable表格通用组件
- 父组件向PageTable传递表头信息参数
List,填充表格内容tableData,同时传递参数chooseSinge控制表格单多选
父组件引用表格子组件 ParentCom.vue
父组件通过chooseSinge和changeMode函数控制单多选切换
<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>