VUE 懒加载树实现增删改查

根据后台接口,一级树节点:一个查询接口,二级树节点:根据一级树节点的id调用接口查询;

实际情况为只有两级节点;测试提出一级树节点的收放按钮如果没有子节点的话不要显示。。。这个让后台接口加个布尔类型的属性,,一级查询接口的时候直接接收就可以了。前端做太麻烦了感觉,还没改。

<template>

  <div id="ath_group">

    <div class="title">功能组</div>

    <div class="condition">

      <div class="option_wrap">

        <el-button type="text" size="medium" @click="add">

          <i class="el-icon-circle-plus"></i>

          新增功能组

        </el-button>

        <el-button type="text" size="medium" @click="edit">

          <i class="el-icon-edit-outline"></i>

          编辑功能组

        </el-button>

        <el-button type="text" size="medium" @click="remove">

          <i class="el-icon-delete-solid"></i>

          删除功能组

        </el-button>

      </div>



    </div>

      <div class="tableTree">

            <div class="header">

                <div class="name">名称</div>

                <div class="customRight">

                    <div class="name">描述</div>

                    <div class="name">操作</div>

                </div>

            </div>

            <div class="wrap">

              <!-- 默认展开全部default-expand-all -->

              <el-tree

              ref="tree"

              node-key="id"

              show-checkbox

              check-strictly



                              :props="props"

                :load="loadNode"

                :expand-on-click-node="false"

                lazy

                @check="change"

                >

                <span class="custom" slot-scope="{ node, data }">

                        <span  :title="data.name">{{ data.name }}</span>

                        <div class="customRight">

                            <div class="name">

                              <span :title="data.description">{{ data.description }}</span>

                            </div>

                            <div class="name">

                              <el-button v-if="node.level===1" type="text" size="medium" @click="open(node,data)">

                                绑定功能

                              </el-button>

                              <el-button v-if="node.level===2" type="text" size="medium" @click="removeR(node,data)">

                                删除

                              </el-button>

                            </div>

                        </div>

                    </span>

              </el-tree>

            </div>

        </div>

         <v-dialog v-if="show" :visible.sync="show" title="功能组" width="440px" @close="close">

           <div class="form_wrap">

            <el-form :model="organData" :rules="rules" ref="organData" inline="" label-width="120px" class="menuForm">

                <el-form-item   label="名称" prop="name" v-if="lodash.isEmpty(organData.id)">

                    <el-input v-model.trim="organData.name" ></el-input>

                </el-form-item>

                <el-form-item   label="描述" prop="description">

                    <el-input v-model.trim="organData.description"></el-input>

                </el-form-item>

                <div class="dialog_footer">

                  <el-button type="primary" @click="submit">保存</el-button>

                  <el-button @click="cancel">取消</el-button>

                </div>

            </el-form>

           </div>

        </v-dialog>

        <v-dialog v-if="showR" :visible.sync="showR" title="绑定功能" width="440px" @close="closeR">

           <div class="form_wrap">

            <el-form :model="dataR" :rules="rulesR" ref="dataR" inline="" label-width="120px" class="menuForm">

              <el-form-item label="功能" prop="rootRouteId">

                    <el-select

                  v-model="dataR.rootRouteId"



                  placeholder="请选择功能" clearable filterable>

                  <el-option

                    v-for="item in allRoutes"

                    :key="item.id"

                    :label="item.routeName"

                    :value="item.id">

                    <span style="float: left">{{ item.routeName }}-{{item.routeKey}}</span>

                  </el-option>

                </el-select>

                </el-form-item>



                <div class="dialog_footer">

                  <el-button type="primary" @click="submitR">保存</el-button>

                  <el-button @click="cancelR">取消</el-button>

                </div>

            </el-form>

           </div>

        </v-dialog>

        <!-- <el-card class="box-card" ref="card" v-show="menuVisible" >

          <div @click="open()" v-if="firstLevel">

            绑定功能

          </div>

          <div @click="removeR()" v-if="!firstLevel">

            删除功能

          </div>

        </el-card> -->



  </div>

</template>



<script type="text/ecmascript-6">

import vDialog from '@/components/dialog.vue';

import _ from 'lodash';



export default {

  components: {

    vDialog

  },

  data() {

    return {

      props: {

        id: 'id',

        label: 'name',

        children: 'children',

        isLeaf: 'leaf'

      },

      data: [],

      dataR: {}, // 绑定的功能组与功能关联数据

      routeData: [], // 中间变量

      allRoutes: [], // 跟路由下拉

      rules: {

        name: [{

          required: true, message: '请输入功能组名称', trigger: 'blur'// 非空校验

        }],

        description: [{

          required: true, message: '请输入功能组描述', trigger: 'blur'// 非空校验

        }]

      },

      rulesR: {

        rootRouteId: [{

          required: true, message: '请选择功能', trigger: 'blur,change'// 非空校验

        }]

      },

      show: false,

      showR: false,

      // menuVisible: false,

      // firstLevel: false,

      lodash: _,

      organData: {

        id: '',

        name: '',

        description: ''

      },



      checkedData: null,

      type: 'add',

      currentData: '', // 定义变量接收该节点所对应的对象

      currentNode: '', // 定义变量接收该节点对应的 Node

      node: {},

      resolve: {},

      rootNode: {},

      rootResolve: {},

      isFirst: true

    };

  },

  created() {

    this.pullData();

    this.getAllRootRoutes();

  },

  methods: {

    // 更新节点

    refreshNode(id) {

      const node = this.$refs.tree.getNode(id);

      node.loaded = false;

      node.expand();

    },

    getAllRootRoutes() {

      this.$api.configManagement.getAllRootRoutes().then((res) => {

        this.allRoutes = res || [];

      }).catch((error) => {

        this.$message.error('功能下拉数据请求失败!');

      });

    },

    open(node, data) {

      this.currentData = data;

      this.currentNode = node;

      this.showR = true;

      this.dataR.resourceGroupId = this.currentData.id;

    },

    loadNode(node, resolve) {

      this.node = node;

      this.resolve = resolve;

      if (this.isFirst) {

        this.rootNode = node;

        this.rootResolve = resolve;

        this.isFirst = false;

      }

      if (node.level === 0) {

        this.$api.configManagement.getAthGroup().then((res) => {

          this.data = res || [];

          return resolve(this.data);

        }).catch((error) => {

          this.$message.error('功能组管理模块 -- 数据请求失败!');

          return resolve([]);

        });

      } else {

        this.$api.configManagement.getAthGroupRelations(node.data.id).then((res) => {

          res.forEach((item, index) => {

            item.id = item.resourceGroupRelationId;

            item.routeId = item.routeDto.id;

            item.name = item.routeDto.routeName;

            item.routeName = item.routeDto.routeName;

            item.description = item.routeDto.routeKey;

            item.leaf = true;

          });

          this.routeData = res || [];

          return resolve(this.routeData);

        }).catch((error) => {

          this.$message.error('功能组管理模块 -- 数据请求失败!');

          return resolve([]);

        });

      }

    },

    add() {

      this.show = true;

      this.type = 'add';

    },

    edit() {

      if (!(this.checkedData && !this.checkedData.leaf)) {

        this.$message('请选择功能组进行操作!');

        return;

      }

      this.checkedData = this.$refs.tree.getNode(this.checkedData.id).data;

      this.show = true;

      this.organData = {

        id: this.checkedData.id,

        name: this.checkedData.name,

        description: this.checkedData.description

      };

      this.type = 'edit';

    },

    remove() {

      if (!(this.checkedData && !this.checkedData.leaf)) {

        this.$message('请选择功能组进行操作!');

        return;

      }

      this.$confirm('此操作将永久删除, 是否继续?', '', {

        confirmButtonText: '确定',

        cancelButtonText: '取消',

        type: 'warning'

      })

        .then(() => {

          this.removeInfo();

        })

        .catch(() => {

          this.$message('已取消删除!');

        });

    },

    removeR(node, data) {

      this.currentData = data;

      this.currentNode = node;

      this.$confirm('此操作将永久删除, 是否继续?', '', {

        confirmButtonText: '确定',

        cancelButtonText: '取消',

        type: 'warning'

      })

        .then(() => {

          this.removeInfoR();

        })

        .catch(() => {

          this.$message('已取消删除!');

        });

    },

    // 绑定跟路由

    submitR() {

      this.$refs.dataR.validate((valid) => {

        if (valid) {

          this.$api.configManagement.addAthGroupRelations(this.dataR).then((res) => {

            this.$utils.vIfElse(res.error, () => {

              this.$message.error(_.get(res.error, 'message'));

            }, () => {

              this.$message.success('保存成功!');

              this.refreshNode(this.dataR.resourceGroupId);

              this.showR = false;

              this.closeR();

            });

          }).catch((error) => {

            this.$message.error(_.get(error, 'response.data.message') || '保存失败!');

          });

        } else {

          return false;

        }

      });

    },

    removeInfoR() {

      this.$api.configManagement.deleteAthGroupRelations(this.currentData.resourceGroupRelationId).then((res) => {

        this.refreshNode(this.currentData.resourceGroupId);

        this.$message.success('删除成功!');

      }).catch((error) => {

        this.$message.error(_.get(error, 'response.data.message') || '删除失败!');

      });

    },

    removeInfo() {

      this.$api.configManagement.deleteAthGroup(this.checkedData.id).then((res) => {

        this.checkedData = {};

        this.rootNode.childNodes = [];

        this.loadNode(this.rootNode, this.rootResolve);

        this.$message.success('删除成功!');

      }).catch((error) => {

        this.$message.error(_.get(error, 'response.data.message') || '删除失败!');

      });

    },

    submit() {

      const method = this.type !== 'add' ? 'updateAthGroup' : 'saveAthGroup';

      this.$refs.organData.validate((valid) => {

        if (valid) {

          this.$api.configManagement[method](this.organData).then((res) => {

            this.$utils.vIfElse(res.error, () => {

              this.$message.error(_.get(res.error, 'message'));

            }, () => {

              this.rootNode.childNodes = [];

              this.loadNode(this.rootNode, this.rootResolve);

              this.show = false;

              this.close();

              this.$message.success('保存成功!');

            });

          }).catch((error) => {

            this.$message.error(_.get(error, 'response.data.message') || '保存失败!');

          });

        } else {

          return false;

        }

      });

    },

    cancel() {

      this.show = false;

      this.close();

    },

    cancelR() {

      this.showR = false;

      this.closeR();

    },

    change(item, keys) {

      if (item.id !== this.checkedId) {

        this.$refs.tree.setCheckedKeys([item.id]);

        this.checkedData = item;

        this.checkedId = item.id;

      } else {

        this.$refs.tree.setCheckedKeys([]);

        this.checkedData = null;

        this.checkedId = null;

      }

    },

    closeR() {

      this.showR = false;

      this.dataR = {

        resourceGroupId: '',

        rootRouteId: ''



      };

    },

    close() {

      this.show = false;

      this.organData = {

        id: '',

        name: '',

        description: ''

      };

    },

    /**

     * 获取全部数据

     */

    pullData() {

      const loading = this.$loading({

        target: document.querySelector('.tableTree'),

        lock: true,

        text: 'Loading',

        spinner: 'el-icon-loading',

        background: 'rgba(0, 0, 0, 0.7)'

      });

      this.loading = true;

      this.$api.configManagement.getAthGroup().then((res) => {

        res.forEach((item, index) => {

          this.$api.configManagement.getAthGroupRelations(item.id).then((res1) => {

            res1.forEach((item1) => {

              item1.id = item.routeDto.id;

              item1.name = item.routeDto.routeName;

              item1.description = item.routeDto.routeName;

            });

            item.children = res1;

          }).catch((error) => {

            item.children = [];

          });

        });

        this.data = res || [];

      }).catch((error) => {

        this.$message.error('功能组管理模块 -- 数据请求失败!');

      }).finally(() => {

        loading.close();

        this.loading = false;

      });

    }



  }



};

</script>



<style lang="scss">

#ath_group {

  .box-card {

width:100px;

height:30px;

position:absolute;

z-index:1000;



}

.el-card__body {

   padding-top: 5px;

    padding-right: 15px;

    padding-bottom: 5px;

    padding-left: 15px;

}

 .el-table--enable-row-hover .el-table__body tr:hover>td{

background-color: #2050a0 !important;

}

.el-button i[class^='icon'] + span {

  margin-left: 5px;

}

.el-button {

  font-size: 14px;

}

.el-button--text {

  color: #989ca2;

}

.el-button--text:hover {

  color: #3b85ff;

}

.el-table__header{

  width: 1950px!important;

}

::-webkit-scrollbar{

  width:0;

}

  height: 100%;

  width: 100%;

  display: flex;

  flex-direction: column;

  .title {

    height: 40px;

    line-height: 40px;

    font-size: 16px;

  }



  .condition {

    color: #fff;

    display: flex;

    justify-content: space-between;

  }



  .table_wrap {

    margin-top: 20px;

    flex: 1;

  }



  .pagination_wrap {

    height: 80px;

    display: flex;

    justify-content: flex-end;

    align-items: center;

  }

    .tableTree {

        flex: 1;

        margin-top: 20px;

        overflow: auto;

        position: relative;

        padding-top: 42px;

        .el-tree {

            background: none;

            color: #fff;

        }

        .el-tree-node__content {

            height: 36px;

        }

        .el-tree-node__content:hover {

            background: #2050a0;

        }

        .el-tree-node:nth-child(2n) {

            background: #2D2D2D;

        }

        .el-tree-node:focus > .el-tree-node__content {

            background: none;

        }

        .customRight {

            display: flex;

            text-align: center;

            font-size: 12px;

            .name {

                width: 200px;

                overflow: hidden;

                margin-right:10px;

                text-overflow: ellipsis;

            }



        }

        .custom,

        .header {

            width: 100%;

            display: flex;

            justify-content: space-between;

            font-size: 12px;

            line-height: 36px;

        }

        .header {

            line-height: 42px;

            background: #383838;

            color: #fff;

            position: absolute;

            top: 0;

            left: 0;

            .name {

                flex: 1;

                text-align: center;

                font-size: 12px;

            }

            .customRight {

                line-height: 42px;

            }

        }

    }

}

.form_wrap {

  padding: 10px 20px 0;

  max-height: 520px!important;

  overflow-y: scroll;

}

.amvs_dialog {

  z-index: 2;

}

.dialog_footer {

  height: 50px;

  padding-right: 30px;

  display: flex;

  justify-content: flex-end;

  align-items: center;

}

.whiteText{

  th{

    color: #fff;

  }

  color: #fff;

}



</style>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值