文章资源连接(如果需要付费,联系我修改即可):https://download.csdn.net/download/Sabrina_cc/87607289
好吧吐槽一下,公司决定之后的技术栈都是vue了,我又从React转战回来了。干巴爹
好的生活方式,是和一群志同道合的人,一起奔跑在理想的路上!回头有一路的故事,低头有坚定的脚步,抬头有清晰的远方。
首先了解Element-UI中定义的基础Tree树组件Element - The world's most popular Vue UI framework
目录
一、页面效果预览
页面解释:页面左边包含组织机构树,点击机构后,右侧列表显示对应公司的人员信息列表,点击即发生页面效果变化,在tree中可以对组织进行搜索,同时右侧可以对人员账户进行查询,并进一步进行新建、编辑和删除操作。
二、Tree组件的设计
1.修改elementUI的tree结构
<template>
<div class="content">
<div>组织列表</div>
<el-input
class="searchInput"
placeholder="输入关键字进行过滤"
v-model="filterText"
suffix-icon="el-icon-search"
>
</el-input>
<div class="treeDiv">
<el-tree
:data="treeData"
:props="defaultProps"
ref="tree"
highlight-current
default-expand-all
:expand-on-click-node="false"
@node-click="handleNodeClick"
node-key="id"
:current-node-key="currentNodeKey"
:filter-node-method="filterNode"
></el-tree>
</div>
</div>
</template>
<script>
import { getOrgTreeData } from "@/api/people/people";
export default {
data() {
return {
filterText: "",
treeData: [],
defaultProps: {
children: "children",
label: "name",
},
currentNodeKey: "",
};
},
watch: {
filterText(val) {
this.$refs.tree.filter(val);
},
},
created() {},
mounted() {
getOrgTreeData().then((res) => {
this.treeData = res.data;
this.currentNodeKey = res.data[0].id;
this.$nextTick(() => {
this.$refs.tree.setCurrentKey(res.data[0].id);
});
this.$emit("getTreeData", res.data[0]);
});
},
methods: {
filterNode(value, data) {
if (!value) return true;
return data.name.indexOf(value) !== -1;
},
handleNodeClick(data) {
this.$emit("getTreeData", data);
},
},
};
</script>
2.绑定属性解释
(1) :data="treeData" 绑定树结构对应的数据,需要在data中定义treeData数组。
data() {
return {
filterText: "",
treeData: [],
defaultProps: {
children: "children",
label: "name",
},
currentNodeKey: "",
};
},
(2):props="defaultProps" 配置treeData数据中对应的属性名称,方便前后端统一属性名以及二级属性名
(3) node-key="id" 对于获取和设置选中节点。获取和设置各有两种方式:通过 node 或通过 key。如果需要通过 key 来获取或设置,则必须设置node-key
。
(4)ref="tree"
(5)highlight-current 是否高亮当前选中节点,默认值是 false。
(6)default-expand-all 是否默认展开所有节点 默认值是 false。
(7):expand-on-click-node="false" 是否在点击节点的时候展开或者收缩节点, 默认值为 true,如果为 false,则只有点箭头图标的时候才会展开或者收缩节点。
(8)@node-click="handleNodeClick" 节点点击时的回调
(9):current-node-key="currentNodeKey" 当前选中的节点,绑定data中自定义的数据,方便后续操作
(10):filter-node-method="filterNode" 对树节点进行筛选时执行的方法,返回 true 表示这个节点可以显示,返回 false 则表示这个节点会被隐藏。
在需要对节点进行过滤时,调用 Tree 实例的filter
方法,参数为关键字。需要注意的是,此时需要设置filter-node-method
,值为过滤函数。
3. 渲染Tree组件数据
(1)对照后端接口
(2)调接口获取组织机构树信息
mounted() {
getOrgTreeData().then((res) => {
this.treeData = res.data;
this.currentNodeKey = res.data[0].id;
this.$nextTick(() => {
this.$refs.tree.setCurrentKey(res.data[0].id);
});
this.$emit("getTreeData", res.data[0]);
});
},
// 组织机构树
export function getOrgTreeData() {
return request({
url: "/api/sys/organization/tree",
method: "get",
});
}
(3)组织机构效果图
三、使用Tree组件实现组织机构树查询列表功能
效果图
1. 搭建主页面核心框架
<div class="content-panel">
<el-col :span="6">
<Tree @getTreeData="getTreeData"></Tree>
</el-col>
<el-col :span="18">
<div class="options-panel f-r-b-c">
<div>
<el-input
v-model="params.username"
placeholder="请输入用户名"
clearable
style="margin-right: 30px; width: 150px"
></el-input>
<el-button
type="primary"
size="mini"
style="margin: 34px"
@click="searchInfoChange"
>搜索</el-button
>
<el-button size="mini" @click="reset">重置</el-button>
</div>
</div>
<div class="buttonDiv">
<el-button type="primary" @click="createDialog">新增</el-button>
</div>
<div class="tableSpan">
<el-table
ref="singleTable"
:data="AccountData"
style="width: 100%"
stripe
fit
highlight-current-row
@row-click="handleClickRow"
>
<el-table-column type="index" label="序号" width="50" align="center"></el-table-column>
<el-table-column
prop="orgName" label="公司名称" width="200" align="center"></el-table-column>
<el-table-column prop="username" label="用户名" width="100" align="center"></el-table-column>
<el-table-column prop="roleIds" label="权限角色" width="150" align="center" > </el-table-column>
<el-table-column prop="status" label="状态" width="100" align="center">
<template slot-scope="scope">
<p v-if="scope.row.status == 1" type="success">启用</p>
<p v-if="scope.row.status == 0" type="warning">禁用</p>
</template>
</el-table-column>
<el-table-column prop="jobDuty" label="备注" width="100" align="center">
</el-table-column>
<el-table-column prop="" label="操作" align="center">
<template slot-scope="scope">
<el-button
type="text"
@click="handleManageRow(scope.row.id)"
>编辑</el-button
>
<el-button
@click="handleDeleteRow(scope.row.id)"
type="text"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<el-pagination
background
class="pagelist"
:current-page.sync="params.pageNum"
:page-size="params.pageSize"
layout="total, prev, pager, next"
:total="params.total"
@current-change="handlePageChange"
/>
</div>
</el-col>
</div>
注意: table绑定的数据是:data="AccountData"
2.显示主页面列表数据
(1)在data中定义查询参数
params: {
username: "", // 用户名
orgId: "", // 组织机构id
status: "", // 状态,0:禁用,1:启用
pageNum: 1, // 当前第几页
pageSize: 10, // 每页数量
total: 0, // 总记录数
},
(2)调接口显示列表数据
查看接口文档可以看出,需要根据Tree中点击的orgaId进行查询
// 获取人员账户列表
getAccount() {
let req = { ...this.params };
delete req.total;
getAccountList(req).then((res) => {
this.AccountData = res.data.list;
this.orgName = res.data.list[0].orgName; // 记录新建时回显的公司全部名称
this.params.total = res.data.totalCount;
});
},
// account.js
// 账户详情
export function getAccountList(data) {
return request({
url: "api/sys/user/list",
method: "post",
data: data,
});
}
3.组件传值显示数据
由于切换机构名称的操作在Tree组件中,但是查询方法getAccount()在父组件中,因此在子组件中切换orgId就需要出发父组件中的方法@getTreedata.
<!--父组件中引用子组件,并把方法传入子组件中-->
<Tree @getTreeData="getTreeData"></Tree>
// Tree子组件中
mounted() {
getOrgTreeData().then((res) => {
this.treeData = res.data;
this.currentNodeKey = res.data[0].id;
this.$nextTick(() => {
this.$refs.tree.setCurrentKey(res.data[0].id);
});
this.$emit("getTreeData", res.data[0]);
});
},
methods: {
filterNode(value, data) {
if (!value) return true;
return data.name.indexOf(value) !== -1;
},
handleNodeClick(data) {
this.$emit("getTreeData", data);
},
},
注意:在mounted中获取组织树对象后需要默认初始化展示第一个元素的列表信息,所以调用了父组件的方法.
在handleNodeClick()中,控制切换点击组织树,获取组织机构值后,调用父组件的方法查询并展示数据
getTreeData(data) {
this.params.orgId = data.id; // 获取选中的组织树的机构id
this.treeNodeData = data;
this.getAccount();
}
},
四、实现右键新增删除的组织机构树
1.安装vue-context-menu
参考链接:vue-context-menu鼠标右键事件_poplargg的博客-CSDN博客_vue-context-menu
(1) 安装vue-context-menu
npm install vue-contextmenu --save
(2)在main.js中引用
import VueContextMenu from 'vue-contextmenu'
Vue.use(VueContextMenu)
2.使用vue-context-menu
<div class="treeDiv">
<el-tree
:data="treeData"
:props="defaultProps"
ref="tree"
highlight-current
default-expand-all
:expand-on-click-node="false"
@node-click="handleNodeClick"
node-key="id"
:current-node-key="currentNodeKey"
:filter-node-method="filterNode"
@node-contextmenu="showMenu"
></el-tree>
<vue-context-menu
:contextMenuData="contextMenuData"
@handleNew="handleNew"
@handleDelete="handleDelete"
></vue-context-menu>
</div>
在data中绑定添加contentMenuData. menuName-菜单名,axis-位置坐标,menulist-菜单选项(对应的方法)为固定写法.
data() {
return {
filterText: "",
treeData: [],
defaultProps: {
children: "children",
label: "name",
},
currentNodeKey: "",
currentNodeNode: {},
// 菜单数据
contextMenuData: {
menuName: "demo",
//菜单显示的位置
axis: {
x: null,
y: null,
},
//菜单选项
menulists: [
{
fnHandler: "handleNew", //绑定事件
btnName: "新增", //菜单名称
},
{
fnHandler: "handleDelete",
btnName: "删除",
},
],
},
dialogFormVisible: false,
form: {
type: 1,
name: "",
creditCode: "",
contactName: "",
contactPhone: "",
},
formLabelWidth: "100px",
};
},
3.修改组织机构树
(1) el-tree添加鼠标右击事件
其中,@node-contextmenu="showMenu" 当某一节点被鼠标右键点击时会触发该事件
showMenu(event, data) {
console.log(data);
this.currentNodeNode = data;
this.$refs.tree.setCurrentKey(data.id);
this.currentNodeKey = data.id;
event.preventDefault();
var x = event.clientX;
var y = event.clientY;
// Get the current location
this.contextMenuData.axis = {
x,
y,
};
},
其主要目的就是在鼠标右击的位置显示菜单,并获取到点击的组织机构树信息。
(2)编辑右键菜单函数
右键菜单包含两个函数【新建】【删除】分别对应handleNew和handleDelete,这部分的内容在contextMenuData中的menulists菜单选项中定义。
<vue-context-menu
:contextMenuData="contextMenuData"
@handleNew="handleNew"
@handleDelete="handleDelete"
></vue-context-menu>
//菜单选项
menulists: [
{
fnHandler: "handleNew", //绑定事件
btnName: "新增", //菜单名称
},
{
fnHandler: "handleDelete",
btnName: "删除",
},
],
(3)实现菜单按钮功能
新建:显示弹框
// 新建 - 弹框
handleNew() {
this.dialogFormVisible = true;
},
删除:调用接口删除组织机构树中的节点
handleDelete() {
this.$confirm("此操作将永久删除该组织, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
deleteOrg(this.currentNodeKey).then((res) => {
if (res.code === 200 && res.success === true) {
this.$message.success(res.message);
this.getTreeData();
}
});
})
.catch(() => {
this.$message({
type: "info",
message: "已取消删除",
});
});
},