前言
使用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>
添加选中的节点的效果
删除掉某个节点的效果