element树形表格更新问题

    技术2023-09-08  96

    环境:

    element-ui:2.13.2

    vue:2.6.6

    问题:

    新增,删除操作,表格不同步更新。表格数据懒加载,表格带有新增、新增子节点、编辑、删除、批量删除操作

    解析:

    表格每一行数据都有id和pid,pid用来标记当前行的父节点,hasChildren标识是否有子节点,children存放子节点的数组。更新节点的关键代码是this.$set(this.$refs.table.store.states.lazyTreeNodeMap, pid, nodes);,这一段代码很多文章可以搜索到,但是没有解决到底哪些pid需要更新数据。用一个数组updateIds记录需要更新的节点,用一个isUpdateList记录是否更新根节点表格数据(没有父节点数据)。

    新增操作,isUpdateList应该设置为true,updateIds置空新增子节点操作,isUpdateList应该设置为false,updateIds设置为只包含当前节点(新增子节点的父节点)id的数组编辑操作 当前节点没有父节点,isUpdateList应该设置为true,updateIds置空当前节点有父节点,isUpdateList应该设置为false,updateIds设置为只包含当前节点(新增子节点的父节点)id的数组 删除操作 当前节点没有父节点,isUpdateList应该设置为true,updateIds置空当前节点有父节点,isUpdateList应该设置为false,updateIds设置为只包含当前节点(新增子节点的父节点)id的数组 批量删除操作,遍历选中的数组selected 存在一个没有父节点的,isUpdateList应该设置为true所有有父节点的进行去重之后存入updateIds

    当isUpdateList为true,需要请求获取根节点接口进行更新表格;当updateIds数组长度有的时候要遍历获取子节点更新this.$set(this.$refs.table.store.states.lazyTreeNodeMap, pid, nodes)。

    注意:

    表格查询,翻页等操作需要把updateIds置空,不要多做更新。

    <template> <div class="page_list"> <div class="table_search"> <div class="search_item"> <el-input v-model="name" placeholder="名称" /> </div> <el-button class="serach_btn" :disabled="loading" icon="el-icon-search" type="primary" @click="searchBtn">查 询</el-button> <el-button class="serach_btn" :disabled="loading" icon="el-icon-refresh-right" @click="clearCondition">重 置</el-button> <el-button class="serach_btn" :disabled="loading" type="success" icon="el-icon-plus" @click="add()" >新增</el-button> <el-popconfirm class="m-l-10" title="是否批量删除?" @onConfirm="multipleDelete"> <el-button slot="reference" class="serach_btn" :disabled="loading" type="danger" icon="el-icon-delete" >批量删除</el-button> </el-popconfirm> </div> <div class="table_place"> <el-table ref="table" v-loading="loading" border row-key="id" :data="list" lazy :load="load" size="small" style="width: 100%" :tree-props="{children: 'children', hasChildren: 'hasChildren'}" @selection-change="selectionChange" > <el-table-column type="selection" width="55" /> <el-table-column prop="name" label="名称" align="center" width="130" /> <el-table-column align="center" label="操作" width="220" fixed="right" > <template slot-scope="{row}"> <el-button type="success" size="mini" @click="add(row)">新增</el-button> <el-button type="primary" size="mini" @click="edit(row)">编辑</el-button> <el-popconfirm class="m-l-10" title="是否删除?" @onConfirm="deleteBtn(row)"> <el-button slot="reference" type="danger" size="mini">删除</el-button> </el-popconfirm> </template> </el-table-column> </el-table> <pagination v-show="total" :total="total" :page.sync="pageNo" :limit.sync="limit" @pagination="pageChange" /> </div> <Operate :is-add="isAdd" :parent="parent" :data="editData" :visible="visibleOperate" @update="getList" @cancel="hiddenOperate" /> </div> </template> <script> import { getLists, getChildrenLists, deleteRows } from '@/api'; import Operate from './operate'; export default { components: { Operate, // 新增编辑操作组件 }, data() { return { name: '', loading: false, isDelete: false, parentIds: [], // 操作时存储有父节点的,即需要更新的 pageNo: 1, limit: 10, total: 0, list: [], multipleSelection: [], isAdd: false, parent: '0', // 新增存储父节点id visibleOperate: false, editData: {}, } }, created() { this.init(); }, methods: { init() { this.getList(); }, getList() { const { pageNo, limit, name } = this; if (!this.loading) { this.loading = true; } else { return; } getLists({ pageNo, limit, name, }).then(res => { if ((res.code == 200) && res.result.records && (res.result.records.length >= 0)) { const records = res.result.records; this.list = records; const parentIds = this.parentIds; if (parentIds.length) { parentIds.forEach(id => { this.updateList(id); }); } this.initPages(res.result); } this.loading = false; }).catch(() => { this.loading = false; }); }, initPages(obj) { this.limit = parseInt(obj.limit); this.total = parseInt(obj.total); this.pageNo = parseInt(obj.pageNo); }, load(tree, treeNode, resolve) { const pid = tree.id; getChildrenLists(pid).then(res => { if (res.code == 200) { const nodes = res.result; resolve(nodes); } }) }, updateList(pid) { getChildrenLists(pid).then(res => { if (res.code == 200) { const nodes = res.result || []; this.$set(this.$refs.table.store.states.lazyTreeNodeMap, pid, nodes); } }) }, pageChange() { this.parentIds = []; this.getList(); }, searchBtn() { this.pageNo = 1; this.parentIds = []; this.getList(); }, clearCondition() { this.parentIds = []; this.pageNo = 1; this.limit = 10; this.name = ''; this.getList(); }, selectionChange(val) { this.multipleSelection = val; }, hiddenOperate() { this.toggleOperate(false); }, toggleOperate(flag) { this.visibleOperate = flag; }, changeIsAdd(flag) { this.isAdd = flag; }, add(row) { if (row) { this.parent = row.id; this.parentIds = [row.id]; this.editData = { ...row }; } else { this.parentIds = []; this.parent = ''; this.scope_code = ''; } this.changeIsAdd(true); this.toggleOperate(true); }, edit(row) { this.editData = { ...row }; this.parent = row.id; if (row.parentId != '') { this.parentIds = [row.parentId]; } else { this.parentIds = []; } this.toggleOperate(true); this.changeIsAdd(false); }, deleteBtn(row) { if (row.parentId != '') { this.parentIds = [row.parentId]; } else { this.parentIds = []; } this.delete([row.id]); }, delete(ids) { const isDelete = this.isDelete; if (!isDelete) { this.isDelete = true; deleteRows(ids).then((res) => { if (res.code == 200) { this.$message.success('删除成功'); this.pageNo = 1; this.limit = 10; this.name = ''; this.getList(); } this.isDelete = false; }).catch(() => { this.isDelete = false; }) } else { this.$message.warning('正在删除'); } }, multipleDelete() { const multipleSelection = this.multipleSelection; if (multipleSelection.length) { const parentIds = []; const data = multipleSelection.map(item => { if (item.parentId != '') { parentIds.push(item.parentId); } return item.id; }); this.parentIds = [...new Set(parentIds)]; this.delete(data); } else { this.$message.warning('请选择删除项'); } }, } } </script>
    Processed: 0.008, SQL: 9