赞
踩
文章资源连接(如果需要付费,联系我修改即可):https://download.csdn.net/download/Sabrina_cc/87607289
好吧吐槽一下,公司决定之后的技术栈都是vue了,我又从React转战回来了。干巴爹
好的生活方式,是和一群志同道合的人,一起奔跑在理想的路上!回头有一路的故事,低头有坚定的脚步,抬头有清晰的远方。
首先了解Element-UI中定义的基础Tree树组件Element - The world's most popular Vue UI framework
目录
页面解释:页面左边包含组织机构树,点击机构后,右侧列表显示对应公司的人员信息列表,点击即发生页面效果变化,在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>
(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
,值为过滤函数。
- 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",
- });
- }
效果图
- <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"
- params: {
- username: "", // 用户名
- orgId: "", // 组织机构id
- status: "", // 状态,0:禁用,1:启用
- pageNum: 1, // 当前第几页
- pageSize: 10, // 每页数量
- total: 0, // 总记录数
- },
查看接口文档可以看出,需要根据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,
- });
- }
由于切换机构名称的操作在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();
- }
- },
参考链接:vue-context-menu鼠标右键事件_poplargg的博客-CSDN博客_vue-context-menu
npm install vue-contextmenu --save
- import VueContextMenu from 'vue-contextmenu'
- Vue.use(VueContextMenu)
- <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",
- };
- },
其中,@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,
- };
- },
其主要目的就是在鼠标右击的位置显示菜单,并获取到点击的组织机构树信息。
右键菜单包含两个函数【新建】【删除】分别对应handleNew和handleDelete,这部分的内容在contextMenuData中的menulists菜单选项中定义。
- <vue-context-menu
- :contextMenuData="contextMenuData"
- @handleNew="handleNew"
- @handleDelete="handleDelete"
- ></vue-context-menu>
- //菜单选项
- menulists: [
- {
- fnHandler: "handleNew", //绑定事件
- btnName: "新增", //菜单名称
- },
- {
- fnHandler: "handleDelete",
- btnName: "删除",
- },
- ],
新建:显示弹框
- // 新建 - 弹框
- 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: "已取消删除",
- });
- });
- },
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。