element树形表格更新问题

环境:

element-ui:2.13.2

vue:2.6.6

问题:

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

解析:

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

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

isUpdateListtrue,需要请求获取根节点接口进行更新表格;当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>

你可能感兴趣的:(框架插件,vue,树形表格,element树形表格更新)