【VUE】封装用户树形选择和部门树形选择控件

用vue实现封装用户树形选择和部门树形选择控件,采用el-tree。方便各个功能模块的使用和以后的开发。

一、封装用户树形选择控件(userTree.vue)

<template><div  style="padding: 10px;"><!-- 选择人员对话框 --><el-input placeholder="输入关键字进行过滤" v-model="filterText"></el-input><div v-loading="loading" style="padding:0px 20px;overflow-y: auto;height: 50vh;margin-top: 10px;"><el-tree class="filter-tree" :data="treeData" show-checkbox :props="defaultProps":filter-node-method="filterNode" :default-checked-keys="checkedKeys" :check-strictly="singleSelection":default-expanded-keys="checkedKeys" @check="handleCheckChange" ref="tree" node-key="id"></el-tree><!--  --></div><div slot="footer" class="dialog-footer" style="text-align: right;padding-top: 20px;"><el-button class="border_buttom" size="small" plain @click="cancel">关 闭</el-button><el-button class="press_button" size="small" @click="handleAddDept">确 定</el-button></div></div>
</template><script>
import {allListUser
} from "@/api/system/user";
import {listDept
} from "@/api/system/dept";
export default {name: "userTree",props: {//选中数据回显checkedKeys: {type: Array,default: () => {return [];}},//是否开启单选singleSelection: {type: Boolean,default: () => {return false;}},},data() {return {loading:true,//是否已勾选判断checkIf:false,services: [],//选人弹窗open: false,//选人过滤filterText: '',//树控件数据treeData: null,defaultProps: {children: 'children',label: 'label'},selectedMumberList: [],}},inject: ["selectUser", "closeUserTree"],watch: {filterText(val) {this.$refs.tree.filter(val);}},created() {this.getUserTree();},methods: {cancel() {this.closeUserTree()this.$refs.tree.setCheckedKeys([]);},filterNode(value, data) {if (!value) return true;return data.label.indexOf(value) !== -1;},handleCheckChange(node, list) {if (this.singleSelection) {if (node.uid != null) {this.checkIf=truethis.selectedMumberList = [];//选中事件在选中后执行,当lis中有两个选中时,使用setCheckedKeys方法,选中一个节点if (list.checkedKeys.length == 2) {this.$refs.tree.setCheckedKeys([node.id]);}this.selectedMumberList.push({uid: node.id,label: node.label,phonenumber:node.phonenumber})} else {this.$message({message: '请选择用户数据',type: 'warning'});}} else {// 获取选中的子节点列表this.checkIf=truethis.selectedMumberList = this.$refs.tree.getCheckedNodes(true, false);this.selectedMumberList = this.selectedMumberList.filter(obj => {return obj.uid != null})}},/** 确定选择人员 */handleAddUser() {let arr = []let userIds = []let phonenumbers = []let form = {userNames: null,userIds: null,phonenumbers:null,}if(this.checkIf){this.selectedMumberList.forEach((obj) => {arr.push(obj.label);userIds.push(obj.uid.replace('u_', ''));phonenumbers.push(obj.phonenumber)})form.userNames = arr.toString()form.userIds = userIds.toString()form.phonenumbers = phonenumbers.toString()this.checkIf=falsethis.selectUser(form)this.$refs.tree.setCheckedKeys([])}else{this.checkIf=falsethis.closeUserTree()}},/** 构建树形数据结构 */getUserTree() {this.loading=true//获取所有部门的数据接口listDept().then(res => {let deptTree = res.data//获取所有用户数据allListUser().then((res) => {this.userList = []for (let i in res.rows) {const obj = {pid: null,id: null,uid: null,label: null,phonenumber:null,}if (res.rows[i].deptId == null || res.rows[i].deptId == "") {obj.pid = -1} else {obj.pid = res.rows[i].deptId}//加‘u_’是为了区分部门id和用户idobj.id = "u_" + res.rows[i].userIdobj.uid = "u_" + res.rows[i].userIdobj.label = res.rows[i].userName//可以按需求补充其他字段,如一下为补充电话号码obj.phonenumber= res.rows[i].phonenumber||'-'this.userList.push(obj)}this.mapTree(deptTree)this.treeData = deptTreethis.loading=false});})},mapTree(data) {data.forEach(ditem => { //遍历树 拼入相应的userif (this.singleSelection && !ditem.uid) {ditem['disabled'] = true}this.userList.forEach(uitem => {if (ditem.id == uitem.pid && ditem.uid == null) {if (!ditem.children) {ditem.children = []}ditem.children.push(uitem)}})if (ditem.children) {this.mapTree(ditem.children)}})},}};
</script><style>
</style>

二、封装部门选择控件(deptTree.vue)

<template><div style="padding: 10px;"><!-- 选择部门对话框 --><el-input placeholder="输入关键字进行过滤" v-model="filterText"> </el-input><div  v-loading="loading"  style="padding:0px 20px;overflow-y: auto;height: 50vh;margin-top: 10px;"><el-tree class="filter-tree" :data="treeData" show-checkbox :props="defaultProps":filter-node-method="filterNode" :default-checked-keys="checkedDeptKeys"  default-expand-all:check-strictly="singleSelection" :default-expanded-keys="checkedDeptKeys" @check="handleCheckChange"ref="tree" node-key="id"></el-tree></div><div slot="footer" class="dialog-footer" style="text-align: right;padding-top: 20px;"><el-button class="border_buttom" size="small"  plain @click="cancel">关 闭</el-button><el-button class="press_button" size="small" @click="handleAddDept">确 定</el-button></div></div>
</template><script>
import {listDept
} from "@/api/system/dept";
export default {name: "deptTree",props: {//选中回显checkedDeptKeys: {type: Array,default: () => {return [];}},//是否单选singleSelection: {type: Boolean,default: () => {return false;}},},data() {return {loading:true,services: [],//选人弹窗open: false,//选人过滤filterText: '',//树控件数据treeData: null,defaultProps: {children: 'children',label: 'label'},selectedMumberList: [],//是否有选择checkIf:false,}},inject: ["selectDept", "closeDeptTree"],watch: {filterText(val) {this.$refs.tree.filter(val);}},created() {this.getDeptTree();},methods: {cancel() {this.closeDeptTree()this.$refs.tree.setCheckedKeys([]);},filterNode(value, data) {if (!value) return true;return data.label.indexOf(value) !== -1;},handleCheckChange(node, list) {if (this.singleSelection) {this.checkIf=truethis.selectedMumberList = [];//node 该节点所对应的对象、list 树目前的选中状态对象//选中事件在选中后执行,当lis中有两个选中时,使用setCheckedKeys方法,选中一个节点if (list.checkedKeys.length == 2) {//单选实现this.$refs.tree.setCheckedKeys([node.id]);}this.selectedMumberList.push({id: node.id,label: node.label})} else {this.checkIf=true// 获取选中的子节点列表this.selectedMumberList = this.$refs.tree.getCheckedNodes(true, false);}},/** 选择部门 */handleAddDept() {let arr = []let deptIds = []this.selectedMumberList.forEach((obj) => {arr.push(obj.label);deptIds.push(obj.id);})let form = {deptNames: null,deptIds: null}if(this.checkIf){form.deptNames = arr.toString()form.deptIds = deptIds.toString()this.checkIf=falsethis.selectDept(form)this.$refs.tree.setCheckedKeys([]);}else{this.checkIf=falsethis.closeDeptTree()}},/** 构建树形数据结构 */getDeptTree() {this.loading=truelistDept().then(res => {this.treeData = res.datathis.loading=false})},}};
</script><style>
</style>

三、控件使用

<template><div><div><el-form ref="form" :model="form" :rules="rules" label-width="90px"><el-row :gutter="24"><el-col :span="12"><el-form-item label="用户1" prop="u1"><el-input v-model="form.u1Name" readonly @click.native="handleUser(1)" placeholder="请选择用户1"><template slot="append"><span class="inco"><i class="el-icon-user"></i></span></template></el-input></el-form-item></el-col><el-col :span="12"><el-form-item label="部门1" prop="d1Name"><el-input v-model="form.d1Name" readonly @click.native="handleDept(1)" placeholder="请输入部门1"><template slot="append"><span class="inco"><i class="el-icon-user"></i></span></template></el-input></el-form-item></el-col></el-row><el-row :gutter="24"><el-col :span="12"><el-form-item label="用户2" prop="u2"><el-input v-model="form.u2Name" readonly @click.native="handleUser(2)" placeholder="请选择用户2"><template slot="append"><span class="inco"><i class="el-icon-user"></i></span></template></el-input></el-form-item></el-col></el-row><el-row :gutter="24"><el-col :span="24"><el-form-item label="用户3" prop="u3"><el-input v-model="form.u3Name" readonly @click.native="handleUser(3)" type="text"placeholder="请选择用户3"><template slot="append"><span class="inco"><i class="el-icon-user"></i></span></template></el-input></el-form-item></el-col></el-row><el-row :gutter="24"><el-col :span="24"><el-form-item label="用户4" prop="u4"><el-input v-model="form.u4Name" readonly @click.native="handleUser(4)" placeholder="请选择用户4"><template slot="append"><span class="inco"><i class="el-icon-user"></i></span></template></el-input></el-form-item></el-col></el-row></el-form></div><el-dialog title="选择人员" :visible.sync="openUserTree" width="500px" append-to-body><userTree v-if="openUserTree" :singleSelection="singleSelection" :checkedKeys="checkedKeys"></userTree></el-dialog><el-dialog title="选择部门" :visible.sync="openDeptTree" width="500px" append-to-body><deptTree :singleSelection="true" :checkedDeptKeys="checkedDeptKeys"></deptTree></el-dialog></div>
</template><script>//引用用户选择和部门选择树形控件import userTree from "/src/components/deptUserTree/userTree.vue"import deptTree from "/src/components/deptUserTree/deptTree.vue"export default {name: "myPage",components: {userTree,deptTree,},data() {return {//用户tree打开openUserTree: false,//部门tree打开openDeptTree: false,//用户tree数据回显checkedKeys: [],//部门tree数据回显checkedDeptKeys: [],// 表单参数form: {},//选人控件是否单选singleSelection: false,};},created() {},//父子组件方法触发的关键provide() {return {selectUser: this.selectUser,closeUserTree: this.closeUserTree,selectDept: this.selectDept,closeDeptTree: this.closeDeptTree,};},methods: {//点击选人输入框,通过i区分不同的字段的处理handleUser(i) {this.userFlag = ithis.checkedKeys = []this.singleSelection = falseif (this.userFlag == 1) {this.singleSelection = trueif (this.form.u1Name != null) {this.checkedKeys = this.form.u1.split(',')}} else if (this.userFlag == 2) {this.singleSelection = trueif (this.form.u2Name != null) {this.checkedKeys = this.form.u2.split(',')}} else if (this.userFlag == 3) {if (this.form.u3Name != null) {this.checkedKeys = this.form.u3.split(',')}} else if (this.userFlag == 4) {if (this.form.u4Name != null) {this.checkedKeys = this.form.u4.split(',')}}//处理数据回显赋值if (this.checkedKeys != []) {this.checkedKeys.forEach((item, index) => {this.checkedKeys[index] = "u_" + this.checkedKeys[index]})}this.openUserTree = true},//选人确定赋值selectUser(e) {if (this.userFlag == 1) {this.form.u1 = e.userIdsthis.form.u1Name = e.userNames} else if (this.userFlag == 2) {this.form.u2 = e.userIdsthis.form.u2Name = e.userNames//赋值联系方式this.form.u2Way = e.phonenumbers} else if (this.userFlag == 3) {this.form.u3 = e.userIdsthis.form.u3Name = e.userNames} else if (this.userFlag == 4) {this.form.u4 = e.userIdsthis.form.u4Name = e.userNames}this.openUserTree = false},//关闭组件closeUserTree() {this.openUserTree = false},//点击选部门输入框handleDept(i) {this.deptFlag = ithis.checkedDeptKeys = []if (this.deptFlag == 1) {if (this.form.d1Name != null) {//处理部门回显选中的到控件里this.checkedDeptKeys = this.form.d1.split(',')}}this.openDeptTree = true},//选择部门selectDept(e) {if (this.deptFlag == 1) {this.form.d1 = e.deptIdsthis.form.d1Name = e.deptNames}this.openDeptTree = false},//关闭部门选择组件closeDeptTree() {this.openDeptTree = false},// 表单重置reset() {this.form = {u1: null,u1Name: null,u2: null,u2Name: null,u3: null,u3Name: null,u4: null,u4Name: null,d1: null,d1Name: null,};this.resetForm("form");},}};
</script><style scoped lang="scss"></style>

三、代码分析

自己看代码的注释吧,重点主要是
1、数据结构的构建,获取用户数据和部门数据接口时按照自己的相关字段调整,还有一些数据权限问题按自己需求规避。
2、父子组件方法的调用,因为会存在各种前端标签包裹问题,目前代码只是简单样例,因此采用了provide()来处理。
3、其他应该没有技术难点。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/56781.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java 类,变量,对象

类的声明 1、类的权限访问修饰符&#xff0c;public 缺省 public修涉的&#xff0c;在同包中可以进行访问&#xff0c;在不同包中也可以进行访问&#xff0c;缺省的修饰符只能在同包中进行访问 2、类的成员&#xff1a;属性&#xff0c;属性如何调用&#xff1f;对象.属性 1、权…

日常随笔1--MySQL中添加Redo日志文件的步骤详解

Redo日志是MySQL中重要的事务日志&#xff0c;用于记录事务对数据库进行的修改操作&#xff0c;确保数据库的持久性和恢复能力。本文将详细介绍在MySQL中添加Redo日志文件的步骤&#xff0c;包括设置Redo日志文件大小、位置和数量等。 1. 确认当前Redo日志文件状态 在添加新的…

xtu oj 原根

文章目录 回顾杂思路c 语言代码 回顾 AB III问题 H: 三角数问题 G: 3个数等式 数组下标查询&#xff0c;降低时间复杂度1405 问题 E: 世界杯xtu 数码串xtu oj 神经网络xtu oj 1167 逆序数&#xff08;大数据&#xff09; 杂 有一些题可能是往年的程设的题&#xff0c;现在搬到…

20255 - 中医方剂学 - 考研 - 执业

第1章 总论 1.我国现存最早的记载方剂的医书是&#xff08;&#xff09;( ) [单选] A.《太平圣惠方》 B.《黄帝内经》 C.《五十二病方》 D.《千金要方》 E.《外台秘要》 正确答案: C 2.我国最早的中医经典理论著作是&#xff08;&#xff09;( ) [单选] A.《伤寒杂病论…

Higress 重磅更新:AI 能力全面开源,云原生能力再升级

作者&#xff1a;澄潭、钰诚 新版本简介 Higress 最新的 1.4 版本基于为通义千问&#xff0c;以及多家云上 AGI 厂商客户提供 AI 网关的积累沉淀&#xff0c;开源了大量 AI 原生的网关能力。同时也在 Ingress、可观测、流控等云原生能力上做了全方位升级&#xff1a; AI 能力…

VS code部署Vue项目Demo

在之前已经在IDEA中部署过vue项目demo。本次在上次基础上进行。 IDEA中Vue的安装和使用【window10】_idea安装vue-CSDN博客 步骤一、安装VSCode 双击安装即可 步骤二&#xff1a;检查npm是否安装 步骤三&#xff1a;检查vue是否安装 &#xff08;vue create 项目名 只要在v…

9.指针与链表

一、指针 1.基本介绍 在程序中&#xff0c;我们的数据都有其存储的地址。在程序每次的实际运行过程中&#xff0c;变量在物理内存中的存储位置不尽相同。不过&#xff0c;我们仍能够在编程时&#xff0c;通过一定的语句&#xff0c;来取得数据在内存中的地址。地址也是数据。…

Leetcode 单词规律

即判断给定的模式字符串&#xff08;pattern&#xff09;和单词字符串&#xff08;s&#xff09;是否遵循相同的对应规则。具体来说&#xff0c;就是要判断 pattern 中的字符与 s 中的单词是否存在一一对应的关系&#xff0c;即双射&#xff08;bijection&#xff09;。 算法思…

安卓无障碍获取录屏权限

每次需要录屏操作时&#xff0c;都会弹窗需要用户手动授权比较麻烦&#xff0c;可以通过无障碍模拟用户点击进行授权。 方法主要有三种&#xff1a; 1.查找“立即开始”&#xff08;华为手机是“允许”&#xff09;节点&#xff0c;模拟点击&#xff1b; Overridepublic void…

【解决办法】git clone报错unable to access ‘xxx‘: SSL certificate problem

git clone 是 Git 版本控制系统中的一个基本命令&#xff0c;用于从远程仓库复制一个完整的版本库到本地。这个命令不仅复制远程仓库中的所有文件&#xff0c;还复制仓库的历史记录&#xff0c;使得你可以在本地进行版本控制操作&#xff0c;如提交&#xff08;commit&#xff…

Electron+Vue实现两种方式的截屏功能

本次介绍的截屏功能一共有两种分别是在electron环境中与非electron环境中 非electron环境 这个环境下会有一些限制&#xff1a; 1.只能截浏览器中的画面 2.如果里面有iframe或者base64的图片会加载不出来&#xff08;这个会有解决办法&#xff09; yarn add -D js-web-scree…

Java爬虫:获取商品评论数据的高效工具

在电子商务的激烈竞争中&#xff0c;商品评论作为消费者购买决策的重要参考&#xff0c;对于商家来说具有极高的价值。它不仅能够帮助商家了解消费者的需求和反馈&#xff0c;还能作为改进产品和服务的依据。Java爬虫技术&#xff0c;以其稳健性和高效性&#xff0c;成为了获取…

基于Spring Cloud的电商系统设计与实现——用户与商品模块的研究(上)

操作系统&#xff1a;Windows Java开发包&#xff1a;JDK1.8 项目管理工具&#xff1a;Maven3.6.0 项目开发工具&#xff1a;IntelliJIDEA 数据库&#xff1a;MySQL Spring Cloud版本&#xff1a;Finchley.SR2 Spring Boot版本&#xff1a;2.0.6.RELEASE 目录 用户模块—user-…

Android 通过计算器暗码启动应用

项目不带通话功能&#xff0c;要求通过计算器输入暗码打开测试应用。 查看布局文件 数字显示控件 packages\apps\ExactCalculator\res\layout\display_one_line.xml ...<com.android.calculator2.CalculatorScrollViewandroid:id"id/formula_container"android:…

golang中的上下文

背景 在Go语言中&#xff0c;使用context包来管理跨API和进程间的请求生命周期是常见的做法。特别是在涉及到并发编程时&#xff0c;如启动协程&#xff08;goroutine&#xff09;来处理异步任务&#xff0c;正确地传递和监听context变得尤为重要。比如&#xff0c;在gin框架中…

YOLO系列入门:1、YOLO V11环境搭建

YOLO了解 yolo检测原理 yolo是目标检测模型&#xff0c;目标检测包含物体分类、位置预测两个内容。目前yolo的开发公司官网为&#xff1a;https://docs.ultralytics.com/zh截止到目前2024年10月&#xff0c;最新的是yolo11。关于YOLO的介绍可以参考这篇文章&#xff1a;https…

NCCL报错

1、报错信息&#xff1a; raise RuntimeError("Distributed package doesnt have NCCL " "built in") RuntimeError: Distributed package doesnt have NCCL built in 2、报错原因&#xff1a; windows系统不支持nccl&#xff0c;采用gloo&#xff1b; …

@PostConstruct和afterPropertiesSet方法执行多次的原因

近日&#xff0c;遇到一个问题&#xff0c;PostConstruct方法会莫名执行多次&#xff0c;单看代码看不出问题&#xff0c;印象中也只会在bean初始化的时候执行一次而已。 然后问AI&#xff0c;问百度&#xff0c;没找到原因。 后面自己猜测&#xff08;现在都是面向猜测编程&am…

Vue3新特性合集

Vue3 简介 ‌‌Vue 3‌ 是‌Vue.js的最新版本&#xff0c;它带来了许多改进和新的特性&#xff0c;旨在提供更好的性能、更强的类型支持以及更灵活的组件开发方式。Vue 3的推出是为了解决Vue 2中存在的一些限制&#xff0c;如响应式系统的限制和虚拟DOM的效率问题。Vue 3在多…

设定义结构变量

在C语言中&#xff0c;可以使用struct关键字来定义结构变量。结构变量是由多个不同类型的成员变量组成的数据类型&#xff0c;可以在一个变量中存储多个相关的数据。 定义结构变量的语法如下&#xff1a; struct 结构名 {数据类型 成员1;数据类型 成员2;... };例如&#xff0…