美文网首页
Vue+ElementUI 搭建后台管理系统(实战系列五)

Vue+ElementUI 搭建后台管理系统(实战系列五)

作者: 祈澈菇凉 | 来源:发表于2021-08-07 17:24 被阅读0次
    前言

    使用ElementUI已经有一段时间了,在一边上手开发后台管理系统的同事,也记录了一些笔记,一直都没有时间将这些零零散散的笔记总结起来,整理成一个比较系统详细一点的教程,可以留着以后来看。

    关于开发过程中,确实使用到很大一部分的文档,都说前端开发离不开文档,重要的话说三遍,一定要多看文档。

    管理后台解决方案

    vue-element-admin 是一个后台前端解决方案,它基于 vue 和 element-ui实现。

    Star指数:69.7k
    Github 地址:https://github.com/PanJiaChen/vue-element-admin
    Demo体验:https://panjiachen.github.io/vue-element-admin/#/dashboard
    官方文档:https://panjiachen.github.io/vue-element-admin-site/zh/

    使用建议
    本项目的定位是后台集成方案,不太适合当基础模板来进行二次开发。因为本项目集成了很多你可能用不到的功能,会造成不少的代码冗余。如果你的项目不关注这方面的问题,也可以直接基于它进行二次开发。


    Vue+ElementUI 搭建后台管理系统(实战系列五)- Elementui Tree 树形控件

    首先看文档,重要的话说三遍
    Tree 树形控件:https://element.eleme.io/#/zh-CN/component/tree

    在文档里面,我们可以get到静态树的基本用法,这里就不复制了。多看几遍也就可以了。

    重要的是,Tree 树形控件的交互是怎么做到的,对于后端给的数据,是如何进行处理的,然后一些回显数据,怎么讲勾选选中的节点数据获取到并且提交,鼠标放在节点上的时候,出现删除的符号,删除节点,这些都是需要下功夫研究一下的。

    步骤,一步一步的来实现:首先最简单的是数据显示的问题,获取数据之后,怎么才能够渲染成为一颗树。

    准备工作
    话不多说了,来看具体的操作吧

    1:在views底下新建一个test文件夹
    里面新建一个vue文件和一个json文件

    image

    2:使用
    mock.json

    {
        "msg": "success",
        "code": 1,
        "data": [
            {
                "id": 2,
                "permissionToken": "data_spectaculars_token1",
                "description": "数据看板",
                "parentId": 1,
                "checked": true
            },
            {
                "id": 3,
                "permissionToken": "data_spectaculars_stat_token2",
                "description": "统计看板",
                "parentId": 2,
                "checked": true
            },
            {
                "id": 4,
                "permissionToken": "data_spectaculars_health_token2",
                "description": "健康看板",
                "parentId": 2,
                "checked": true
            },
            {
                "id": 1,
                "permissionToken": "system_token0",
                "description": "系统权限",
                "parentId": 0,
                "checked": false
            },
            {
                "id": 5,
                "permissionToken": "account_management_token1",
                "description": "账户管理",
                "parentId": 1,
                "checked": false
            },
            {
                "id": 6,
                "permissionToken": "account_management_user_token2",
                "description": "用户管理",
                "parentId": 5,
                "checked": false
            },
            {
                "id": 7,
                "permissionToken": "account_management_permission_token2",
                "description": "权限管理",
                "parentId": 5,
                "checked": false
            }
        ]
    }
    
    默认展开和默认选中

    分别通过default-expanded-keys设置默认展开的节点。
    需要注意的是,此时必须设置node-key,其值为节点数据中的一个字段名,该字段在整棵树中是唯一的。

    我这里的要求是获取到数据之后,将所有的数据默认展开显示直接在el-tree上添加default-expand-all属性来默认展开所有节点。

    <el-tree
          :data="treeData"
          show-checkbox
          default-expand-all
          node-key="id"
          ref="tree"
          highlight-current
          :props="defaultProps"
          @check="checkHandler"
        >
        </el-tree>
    
    vue如何获取Elementui Tree 树形控件当前选中的节点

    这里需要用到,树文件勾选事件在el-tree上绑定@check="checkHandler"事件

    //树文件勾选事件
        checkHandler(...value) {
          let a = value[1].checkedNodes.map((a) => a.description);
          let b = value[1].checkedNodes.map((a) => a.permissionToken);
          console.log(a);
          this.questionForm.description = a;
          this.questionForm.permissionToken = b;
        },
    
    Elementui Tree 树形控件删除子节点

    功能:当鼠标划过Tree 树形控件的节点的时候,会出现一个删除的按钮
    点击删除按钮,会出现弹框询问是否删除
    选中删除,则删除树节点(最上层的父节点不可删除)

    1:第一步,当然是添加删除元素了

    在文档里面有这样的说明:

    可以通过两种方法进行树节点内容的自定义:render-content和 scoped slot。使用render-content指定渲染函数,该函数返回需要的节点区内容即可。渲染函数的用法请参考 Vue 文档。使用 scoped slot 会传入两个参数node和data,分别表示当前节点的 Node 对象和当前节点的数据。注意:由于 jsfiddle 不支持 JSX 语法,所以render-content示例在 jsfiddle 中无法运行。但是在实际的项目中,只要正确地配置了相关依赖,就可以正常运行。

    所以
    我们今天使用的还是

    :render-content="renderContent"
    
    
    image

    直接将文档里面的这个例子,赋值到我们的项目代码里面吧,直接简单且粗暴。

    image

    需要注意的地方
    因为功能是,当鼠标划过树形控件的子节点的时候
    才会出现了那个删除的图标
    需要在渲染的时候设置一下isHover: false

     isHover: false,
    
    
    image

    最后,test.vue

    <template>
      <div class="ztree">
        <el-tree
          :data="treeData"
          show-checkbox
          default-expand-all
          node-key="id"
          ref="tree"
          highlight-current
          :props="defaultProps"
          @check="checkHandler" 
          :render-content="renderContent"
        >
        </el-tree>
        <el-button type="primary" @click="createData()">确定</el-button>
      </div>
    </template>
    <script>
    //调用删除接口
    // import { deleteSubject} from "@/api/data/organ";
    
    export default {
      data() {
        return {
          setTree: [],
          defaultProps: {
            children: "children",
            label: "description",
          },
          treeData: [],
          organList: [],
          questionForm: {
          },
        };
      },
     
      created() {
        //加载树节点
        this.getZtreeList();
      },
      methods: {
         renderContent(h, { node, data, store }) {
          console.log(data);
          return (
            <span
              class="custom-tree-node"
              on-mouseenter={() => (data.isHover = true)}
              on-mouseleave={() => (data.isHover = false)}
            >
              <span>{data.description}</span>
              {data.parentId !== 0 && data.isHover && (
                <i
                  class="el-icon-error danger"
                  on-click={(e) => {
                    e.stopPropagation();
    
                    this.remove(node, data);
                  }}
                ></i>
              )}
            </span>
          );
        },
        remove(node, data) {
          this.$confirm("此操作将永久删除该条目, 是否继续?", "提示", {
            confirmButtonText: "确定",
            cancelButtonText: "取消",
            type: "warning",
          })
            .then(() => {
              this.handleDelete(null, data);
              if (data.parentId === 0) {
                return;
              }
              const parent = node.parent;
              const children = parent.data.children || parent.data;
              const index = children.findIndex((d) => d.id === data.id);
              children.splice(index, 1);
              // 发请求删除
              this.$message({
                type: "success",
                message: "删除成功!",
              });
            })
            .catch(() => {
              this.$message({
                type: "info",
                message: "已取消删除",
              });
            });
        },
    
         //调用删除接口
        handleDelete(index, row) {
         //这里不多说了,根据自己的实际情况,填写删除接口
        },
    
        //树文件勾选事件
        checkHandler(...value) {
          let a = value[1].checkedNodes.map((a) => a.description);
          let b = value[1].checkedNodes.map((a) => a.permissionToken);
          console.log(a);
          this.questionForm.description = a;
          this.questionForm.permissionToken = b;
        },
    
        //获取树权限节点接口定义
        getZtreeList() {
          this.dataLoading = true;
          import("./mock").then((res) => {
            this.setTree = res.data;
            this.organList = res.data.map((a) => ({
              label: a.description,
              value: a.id,
            }));
    
            this.getListData();
            this.dataLoading = false;
          });
        },
    
        //对json的格式的转化
        getListData() {
          let dataArray = [];
          this.setTree.forEach(function (data) {
            let parentId = data.parentId;
            if (parentId === 0) {
              let objTemp = {
                id: data.id,
                description: data.description,
                permissionToken: data.permissionToken,
                parentId: parentId,
              };
    
              dataArray.push(objTemp);
            }
          });
          this.treeData = this.data2treeDG(this.setTree, dataArray);
        },
        data2treeDG(datas, dataArray) {
          for (let j = 0; j < dataArray.length; j++) {
            let dataArrayIndex = dataArray[j];
            let childrenArray = [];
            let Id = dataArrayIndex.id;
            for (let i = 0; i < datas.length; i++) {
              let data = datas[i];
    
              let parentId = data.parentId;
              if (parentId == Id) {
                //判断是否为儿子节点
                let objTemp = {
                  id: data.id,
                  description: data.description,
                  permissionToken: data.permissionToken,
                  parentId: parentId,
                  isHover: false,
                };
                childrenArray.push(objTemp);
              }
            }
            dataArrayIndex.children = childrenArray;
            if (childrenArray.length > 0) {
              this.data2treeDG(datas, childrenArray);
            }
          }
    
          return dataArray;
        },
    
        //添加
        async createData() {
          const params = this.questionForm;
          alert(JSON.stringify(params));
        },
      },
    };
    </script>
    <style lang="scss">
    .danger {
      color: red;
    }
    </style>
    
    

    添加选中的节点的效果



    删除掉某个节点的效果


    图片.png

    相关文章

      网友评论

          本文标题:Vue+ElementUI 搭建后台管理系统(实战系列五)

          本文链接:https://www.haomeiwen.com/subject/vwzsvltx.html