element-plus弹窗内分页表格保留勾选项
情境
vue项目中使用element-plus组件,页面中某个选择项选择方式为:点击选择框打开弹窗,弹窗内部为表格,表格支持勾选,表格勾选项作为选择框的已选项。其中表格数据是接口分页获取的,表格支持搜索,该选择项组件在页面中存在复用,需要保证勾选项与已选项始终保持一致。
父组件
关键::destroy-on-close="true"
关闭弹窗时需要销毁弹窗内容使弹窗内表格回到初始化状态,若不销毁则需要处理勾选项数据与表格内置勾选状态冲突的情况。最终选择牺牲很小性能以解决问题,若有不需要销毁的方式欢迎一起讨论
html
<!-- 涉及项目内的变量和函数与主题无关,不在此列出赘述 -->
<el-dialog
v-model="memberDialog.visible"
title="请选择"
width="1000"
:before-close="() => {memberDialog.visible = false}"
:destroy-on-close="true"
>
<member-select class="member-content" @success="saveMember" :value="memberDialog.value" />
</el-dialog>
子组件
模板定义
reserve-selection
与row-key
配合使用使表格数据刷新后依旧保留选项
html
<el-table
ref="multipleTableRef"
:data="tableData"
row-key="memberId"
style="width: 100%; height: 100%;"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" :reserve-selection="true"/>
<el-table-column property="member" label="人员名称"/>
<el-table-column property="phoneNumber" label="手机号码"/>
<el-table-column property="positionName" label="人员职位"/>
</el-table>
关键函数定义
javascript
const tableData = ref([])
const selectItems = ref([]) // 存储表格勾选项
const multipleTableRef = ref(null as any)
const isAutoCheck = ref(true) // 判断是toggleRowSelection还是表格内置自动更新勾选状态
const props = defineProps<{
value: Array<any>
}>();
// 针对表格数据变化根据勾选项进行手动修改行的勾选状态
const toggleSelect = () => {
tableData.value.forEach((item: any) => {
let selected = selectItems.value.some(selectItem => selectItem.memberId === item.memberId);
let isChecked = multipleTableRef.value.getSelectionRows().some(row => row.memberId === item.memberId);
// 对于勾选项已勾选但行勾选状态为未勾选的进行手动勾选
if(selected && !isChecked) {
isAutoCheck.value = false
multipleTableRef.value.toggleRowSelection(item, selected)
}
})
}
// 根据传入值设置表格勾选项
watch(
() => props.value,
(newVal, oldVal) => {
selectItems.value = newVal
}, {
immediate: true
}
)
// toggleRowSelection会触发selection-change,此时不更新勾选项,否则将造成勾选项重复
const handleSelectionChange = (selections: Array<any>) => {
if(isAutoCheck.value) selectItems.value = selections
else isAutoCheck.value = true
}
// 获取数据更新表格时toggleSelect根据存储的勾选项更新表格行勾选状态
const getTable = async () => {
const res:any = await getMember({
name: filters.name,
phoneNumber: filters.phoneNumber,
saleAreaCodePath: filters.saleAreaCodePath,
positionName: filters.positionName,
pageindex: pagination.index,
pagesize: 20
})
if(res.code === 200) {
const data = res.data.data
tableData.value = data.list
pagination.total = Number(data.total)
toggleSelect()
}
}
getTable()