24小时学会网站建设seo教学
需求:不管是页面切换还是通过搜索获取数据,都要保持已选中的行保持勾选状态,同时将选中行的内容以标签的形式显示出来,当点击关闭标签时可以对应取消选中状态,点击行中的任意位置也可以切换选中状态,单独勾选复选框一样可以达到要求。
由于需求相对还是蛮复杂的,直接使用row-key和reserve-selection,难以实现。所以直接通过书写代码来控制表格的勾选状态。
注意:我使用的是vue3 + ts!!!!
1. 第一步:书写html代码
给el-table添加对应勾选的监听事件,row-click用于监听鼠标选中某行时的勾选事件(不需要可去掉,我的需求是鼠标选中某行也要勾选);selection-change用于监听鼠标点击某行前面的勾选框、选中某行实现的勾选、表格左上角的全选,三种状态的事件;select用于监听框勾选数据行的 Checkbox 时触发的事件;select-all用于监听鼠标点击表格左上角的全选框。
<!-- 已选择点检项 --> <el-rowalign="middle"class="selected"justify="space-between"type="flex" ><el-col :span="24"><span>已选择:</span><template v-if="selectedCheckOptions"><el-tagv-for="(item, i) in selectedCheckOptions":key="i"closable:disable-transitions="false"@close="handleCloseTag(item, i)">{{ item }}</el-tag></template></el-col> </el-row> <!-- 表格部分 --> <el-tableref="multipleTableRef":data="gridData":header-cell-style="{'background-color': '#fafafa',color: '#000',}"size="small"style="width: 100%"@row-click="handleClickTableRow"@select="onTableSelect"@select-all="selectSingleTableAll"@selection-change="handleChange" ><el-table-column type="selection" width="50" /><el-table-column fixed label="序号" type="index" width="60" /><el-table-column label="点检项" prop="itemName" /><el-table-column label="分类" prop="itemTypeName" /> </el-table> <!-- 分页 --> <div class="page"><el-paginationv-model:currentPage="currentPage"layout="total, prev, pager, next"small:total="total"@current-change="handleCurrentChange"/> </div>
2. 所需数据
// 只将表格中设计到需求的重要数据进行展示 const modelInfo = reactive({// 当前所在页面的表格数据gridData: [],// 添加点检项表格全部数据tableData: [],tableAllSelectedId: [] as any, // 保存表格勾选的全部idtableAllSelectedRow: [] as any, // 保存表格勾选的行数据selectedCheckOptions: [] as any, // 已选择的点检项 })// 获取已选择的点检项 modelInfo.selectedCheckOptions = computed(() => {return modelInfo.tableAllSelectedRow.map((r: any) => r.itemName) })
3.所需方法
(1)从后台获取表格的分页数据的方法
// 获取表格数据的方法 (这里根据后端给的接口进行获取即可) const getCheckItemData = () => {checkItemList({itemName: formInline.checkOption,itemTypeId: formInline.itemTypeId[formInline.itemTypeId.length - 1],filter: [],paging: {dir: 'DESC',limit: modelInfo.pageSize,page: modelInfo.currentPage,sort: 'createTime',start: 0,},}).then((res: any) => {modelInfo.gridData = res.data.records// 条数必须是数字才可以显示在分页控件中modelInfo.total = parseInt(res.data.total)// 关键代码(实现已勾选行数据保持选中状态)nextTick(() => {modelInfo.gridData.forEach((item: any) => {if (modelInfo.tableAllSelectedId.indexOf(item.itemId) > -1) {multipleTableRef.value?.toggleRowSelection(item, true)} else {multipleTableRef.value?.toggleRowSelection(item, false)}})})}) }
(2)当选择项发生变化时触发的方法
// 当选择项发生变化时会触发该事件 const handleChange = (val: any) => {// 将获取到的id存入tableAllSelectedId数组中val.forEach((item: any) => {if (modelInfo.tableAllSelectedId.indexOf(item.itemId) === -1) {modelInfo.tableAllSelectedId.push(item.itemId)modelInfo.tableAllSelectedRow.push(item)}}) }
(3)点击表格某一行的方法
// 点击表格某一行的方法 const handleClickTableRow = (row: any) => { // 判断当前行是否已选中if (findIndexInObejctArr(JSON.parse(JSON.stringify(modelInfo.tableAllSelectedRow)),row,'itemId') > -1) {const index = modelInfo.tableAllSelectedId.indexOf(row.itemId)modelInfo.tableAllSelectedId.splice(index, 1)modelInfo.tableAllSelectedRow.splice(index, 1)nextTick(() => {modelInfo.gridData.forEach((item: any) => {if (modelInfo.tableAllSelectedId.indexOf(item.itemId) > -1) {multipleTableRef.value?.toggleRowSelection(item, true)} else {multipleTableRef.value?.toggleRowSelection(item, false)}})})} else {multipleTableRef.value?.setCurrentRow(row)multipleTableRef.value!.toggleRowSelection(row, true)} }
(4)勾选数据行的 Checkbox 时触发的方法
// 勾选数据行的 Checkbox 时触发的方法 const onTableSelect = (rows: any, row: any) => {// 判断是点击了表格勾选还是取消勾选,true为选中,0或false是取消选中const selected = rows.length && rows.indexOf(row) !== -1if (!selected) {// 如果点击取消勾选const index = modelInfo.tableAllSelectedId.indexOf(row.itemId)modelInfo.tableAllSelectedId.splice(index, 1) // 取消勾选,则删除idmodelInfo.tableAllSelectedRow.splice(index, 1) // 取消勾选,则删除数据} }
(5)表格全选触发的方法
// 表格全选触发的方法 const selectSingleTableAll = (selection: any) => {// 获取当前页码所显示的数据const a: any = modelInfo.gridData// 获取当前页勾选的数据const b = selectionlet flag_inCurrentPageselection.forEach((item: any) => {if (item.itemId === a[0].itemId) {flag_inCurrentPage = truereturn}})const flag = a.length === b.length && flag_inCurrentPageif (flag) {// 切换成了全选状态modelInfo.gridData.forEach((r: any) => {if (modelInfo.tableAllSelectedId.indexOf(r.itemId) === -1) {modelInfo.tableAllSelectedId.push(r.itemId) // 如果点击全选就保存全部idmodelInfo.tableAllSelectedRow.push(r) //如果点击全选就保存全部数据}})} else {// 切换成了非全选状态modelInfo.tableAllSelectedId = []modelInfo.tableAllSelectedRow = []} }
(6)查找对象在对象数组中位置的方法
// 查找对象在对象数组中的位置 findIndexInObejctArr: function(arr, obj) {for (let i = 0, iLen = arr.length; i < iLen; i++) {if (arr[i].deliverId === obj.deliverId) {return i}}return -1 }
(7)删除标签的方法
// 删除标签的方法 const handleCloseTag = (tag: string, index: number) => {// 先删除保存表格勾选的全部行数据中对应的数据,以及保存表格勾选的全部行id中对应的数据modelInfo.tableAllSelectedId.splice(index, 1)modelInfo.tableAllSelectedRow.splice(index, 1)// 再根据已勾选的全部id来将对应行选中nextTick(() => {modelInfo.gridData.forEach((item: any) => {if (modelInfo.tableAllSelectedId.indexOf(item.itemId) > -1) {multipleTableRef.value?.toggleRowSelection(item, true)} else {multipleTableRef.value?.toggleRowSelection(item, false)}})}) }
(8)切换页码的方法
const handleCurrentChange = (val: number) => { modelInfo.currentPage = valgetCheckItemData() }
(9)查询方法
// 搜索方法 const onSearch = () => {modelInfo.currentPage = 1getCheckItemData() }
(10)确认添加的方法(由于我的表格是出现在弹出层中的,故增加了此方法,该方法和本文章的需求无关,可以直接忽视)
// 确认添加点检项的方法 const confirmAdd = () => {modelInfo.checkOptions = modelInfo.tableAllSelectedRowdialogAddVisible.value = false// 清除搜索内容formInline.checkOption = ''formInline.itemTypeId = []modelInfo.currentPage = 1getCheckItemData() }
4.效果图
(1)选中的会在上面同步显示
(2)跨行也能保留选中状态和标签
(3)搜索也一样能保留选中状态
借鉴:elementui el-table表格实现跨页(翻页)保存勾选状态(后端分页)_公孙元二的博客-CSDN博客_el-table跨页勾选