记录一下最近在做一个的表格数据多选功能。需求大致为支持多选、支持跨分页的连续选择、支持通过查询框后手动选择数据(我是后端选手,前端不太熟悉单纯记录~)。
主要思路为:
- 将table中的唯一id,存入数组tableIds中进行记录。
- 在选中事件中,若当前为新增则存id,若为移除则remove该id。
- 在分页事件触发时(同时会触发表格的选中事件,在这里我检查如果当前为分页事件标志则不进行表格的选中事件),首先清除表格的所有选中项 table.value.clearSelection() ,然后查询当前页的数据是否存在已经选中的数据,若存在则选中 table.value.toggleRowSelection(index)。
- 在search事件触发时(同时会触发表格的选中事件,在这里我不进行表格的选中事件逻辑),和上面一样重新构造选中数据。
templete
XML
<template>
<view>
<uni-section>
<uni-search-bar @confirm="search" :focus="true" v-model="queryParam.name" @blur="blur" @input="input"
@cancel="cancel" @clear="clear">
</uni-search-bar>
</uni-section>
<view class='table-container'>
<uni-table
style='margin: 0;padding: 0'
ref="table"
:loading="loading"
border
stripe
type="selection"
emptyText="暂无更多数据"
@selection-change="selectionChange">
<uni-tr>
<uni-th :style="{ width: '100px', textAlign: 'center',height: '50px' }">姓名</uni-th>
<uni-th :style="{ width: '100px', textAlign: 'center' ,height: '50px'}">工号</uni-th>
<uni-th :style="{ width: '200px', textAlign: 'center' ,height: '50px'}">直属部门</uni-th>
</uni-tr>
<uni-tr style='height: 40px ;flex: 1 ' v-for="(item, index) in tableData" :key="index">
<uni-td>{{ item.name }}</uni-td>
<uni-td>{{ item.employeeNo }}</uni-td>
<uni-td>{{ item.department }}</uni-td>
</uni-tr>
</uni-table>
<view>
<uni-pagination
how-icon
:page-size="pageSize"
:current="pageCurrent"
:total="total"
@change="change"/>
</view>
</view>
<button
:disabled='isSubmitButtonDisabled'
class='btn-submit'
type='primary'
@click='submit'>提交
</button>
</view>
</template>
ts相关代码
TypeScript
<script lang='ts' setup>
import {watch, onMounted, reactive, ref} from 'vue';
import {getHttp} from '@/services';
import {qcStore} from "@/store/qcStore";
import {onShow} from "@dcloudio/uni-app";
let tableData = ref([]);
let pageSize = ref(10);
let pageCurrent = ref(1);
let total = ref(0);
let loading = ref(false);
let disableSelectionChangeFlag = ref(false);
let isSubmitButtonDisabled = ref(true);
const table = ref();
const queryParam = reactive({
name: ''
})
let qc = qcStore();
onMounted(() => {
getData(pageSize.value, pageCurrent.value);
});
onShow(() => {
qc.clearPersonIdsList();
qc.clearPersonNamesList();
})
let tableIds = ref([]);
let tableNames = ref([]);
let preItems = ref([]);
let currentItems = ref([]);
async function search(res) {
pageCurrent.value = 1;
await getData(pageSize.value, pageCurrent.value);
clearAndreSelect();
}
function input(res) {
queryParam.name = res;
}
async function clear(res) {
queryParam.name = '';
pageCurrent.value = 1;
await getData(pageSize.value, pageCurrent.value);
clearAndreSelect();
}
function blur(res) {
}
async function cancel(res) {
queryParam.name = '';
pageCurrent.value = 1;
await getData(pageSize.value, pageCurrent.value);
clearAndreSelect();
}
// 多选
function selectionChange(e) {
if (!disableSelectionChangeFlag.value) {
currentItems.value = e.detail.index;
//新增项
let addItem = currentItems.value.filter(item => !preItems.value.includes(item));
//删除项
let removeItem = preItems.value.filter(item => !currentItems.value.includes(item));
preItems.value = [...currentItems.value];
if (addItem.length > 0) {
addItem.forEach(i => {
let personId = tableData.value[i].id;
if (!tableIds.value.includes(personId)) {
tableIds.value.push(personId);
tableNames.value.push(tableData.value[i].name);
}
})
}
if (removeItem.length > 0) {
removeItem.forEach(i => {
let personId = tableData.value[i].id;
if (tableIds.value.includes(personId)) {
tableIds.value = tableIds.value.filter(a => personId != a);
tableNames.value = tableNames.value.filter(a => a != tableData.value[i].name)
}
})
}
}
}
async function change(e) {
disableSelectionChangeFlag.value = true;
await getData(pageSize.value, e.current);
clearAndreSelect();
disableSelectionChangeFlag.value = false
pageCurrent.value = e.current;
}
function clearAndreSelect() {
disableSelectionChangeFlag.value = true;
table.value.clearSelection()
preItems.value.length = 0;
currentItems.value.length = 0;
tableData.value.forEach(data => {
if (tableIds.value.includes(data.id)) {
let index = tableData.value.indexOf(data);
console.log(index)
table.value.toggleRowSelection(index)
preItems.value.push(index);
currentItems.value.push(index);
}
})
disableSelectionChangeFlag.value = false;
}
function getData(pageSize: number, currentPage: number) {
return new Promise((resolve, reject) => {
getHttp('kengic-boot/qctask/qcTask/getQcReviewPerson', {
params: {
pageSize: pageSize,
pageCurrent: currentPage,
name: queryParam.name
}
}).then((data) => {
tableData.value = data.records;
total.value = data.total;
pageCurrent.value = data.current;
resolve();
})
})
}
watch(() => tableIds, (newValue) => {
if (Object.keys(newValue.value).length > 0) {
isSubmitButtonDisabled.value = false;
} else {
isSubmitButtonDisabled.value = true;
}
}, {deep: true, immediate: true})
/**
* 提交.
*/
function submit() {
//跳转到异常填写界面
qc.setPersonIdsList(tableIds.value);
qc.setPersonNamesList(tableNames.value);
console.log(qc.getPersonIdsList)
uni.navigateBack({
url: '/pages-manage/equipment-patrol/patrol-task/patrol-task-report'
})
}
</script>