文章目录
- 👉 前言
- 👉 一、效果演示
- 👉 二、原理
- 👉 三、实现代码
- 往期内容 💨
👉 前言
在 Vue + elementUi 开发中,实现通过树状组织机构,点击查询用户信息联动效果! 组件较为简单,可以直接嵌入到需要使用的位置,具体操作还得看各位大佬如何使用! 纯记录!
👉 一、效果演示
话不多说,先上效果图! 白嫖万岁!当然,如果有帮助,希望不要吝啬你的点赞呀!
👉 二、原理
通过组合element-ui 中的 tree 和 table组件,实现联动效果,单选(有需要可以自己改成多选)用户信息,传出到父组件中,通过触发checkValue
方法接收。
👉 三、实现代码
> HTML模板(父组件中)
<!-- getOrganizationListWithType getListUserByOrgIdAndPositionId 为封装的axios请求接口名称 -->
<template>
<el-dialog
:title="'合规模型异常' + currentType"
:visible.sync="dialogVisible"
:width="currentType === '派发' ? '70%' : '41.7%'"
:modal="false"
:close-on-click-modal="false"
custom-class="processDialog">
<el-form
:model="ruleForm"
:rules="rules['派发']"
ref="ruleForm"
:key="currentType"
class="demo-ruleForm">
<checkDispatcher-tree
v-if="dialogVisible"
:treeProps="defaultProps"
:accordion="true"
getTreeUrl="getOrganizationListWithType"
getTableUrl="getListUserByOrgIdAndPositionId"
@checkValue="checkValue"
/>
<el-form-item
label=""
prop="userId"
></el-form-item>
</el-form>
</el-dialog>
</template>
<script>
export default {
name: "tableCol",
props: {},
data() {
return {
defaultProps: {
children: "list",
label: "orgName",
value: "orgId"
},
};
},
methods: {
// 获取选中的用户信息
checkValue(valArr) {
this.ruleForm.userId = valArr.length > 0 ? valArr[0].userId : "";
this.ruleForm.zrbmId = valArr.length > 0 ? valArr[0].orgId : "";
},
}
};
</script>
> HTML模板(子组件使用)
<template>
<div class="checkDispatcher-tree">
<div class="tree_content">
<el-input
clearable
placeholder="输入关键字进行过滤"
v-model="filterText">
</el-input>
<el-tree
id="tree-option"
ref="selectTree"
:accordion="accordion"
:data="options"
:props="treeProps"
:node-key="treeProps.value"
:default-expanded-keys="defaultExpandedKey"
:filter-node-method="filterNode"
:expand-on-click-node="false"
@node-click="handleNodeClick">
</el-tree>
</div>
<div class="table_content">
<el-form :inline="true" ref="params" class="selectBox" :model="params">
<!-- <el-button type="primary" style="float: left;">生成报告</el-button> -->
<span></span>
<span>
<el-form-item>
<bda-search-input
v-model="params.keyword"
placeholder="请输入关键字"
@search="queryTableList(true)"
@clear="queryTableList(true)"
style="width: calc(15vw);"
size="mini"
></bda-search-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="queryTableList(true)">
查询
</el-button>
</el-form-item>
</span>
</el-form>
<el-table
ref="multipleTable"
:data="userTableData"
style="width: 100%;"
:height="tableHeight"
row-key="userId"
v-loading="tableLoading"
element-loading-text="拼命加载中"
element-loading-spinner="el-icon-loading"
element-loading-background="rgba(0, 0, 0, 0.8)"
@selection-change="handleSelectionChange">
<el-table-column
align="center"
type="selection"
:selectable="selectable"
reserve-selection
width="60">
</el-table-column>
<el-table-column
prop="userName"
label="用户姓名"
min-width="120"
align="center"
show-overflow-tooltip
>
</el-table-column>
<el-table-column
prop="userName"
label="职务(岗位)"
min-width="150"
align="center"
show-overflow-tooltip
>
</el-table-column>
<el-table-column
prop="orgName"
label="归属机构单位"
min-width="150"
align="center"
show-overflow-tooltip
>
</el-table-column>
<el-table-column
prop="userTel"
label="联系电话"
min-width="200"
align="center"
show-overflow-tooltip
>
</el-table-column>
</el-table>
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="params.current"
:page-sizes="[10, 50, 100, 200]"
:page-size="params.size"
background
layout="prev, pager, next, sizes, jumper, total"
:total="params.total"
>
</el-pagination>
</div>
</div>
</template>
<script>
import Interface from "@/base/mixin/common.js";
import Interface_1 from "@/base/mixin/risk-control-center.js";
import Interface_2 from "@/base/mixin/disposal-center.js";
export default {
name: "checkDispatcher-tree",
mixins: [Interface, Interface_1, Interface_2],
props:{
// 配置项
treeProps:{
type: Object,
default: () => {
return {
value:'id', // ID字段名
label: 'label', // 显示名称
children: 'children' // 子级字段名
};
}
},
// 自动收起
accordion:{ type:Boolean, default: () => { return false } },
// 点击树状节点触发接口名称
getTreeUrl: {
type: String,
require: true,
default: () => {
return 'getOrganizationListWithType'
}
},
// 点击树状节点触发接口名称
getTableUrl: {
type: String,
require: true,
default: () => {
return 'getListUserByOrgIdAndPositionId'
}
}
},
watch: {
filterText(val) {
this.$refs.selectTree.filter(val);
}
},
data() {
return {
tableHeight: window.innerHeight*0.45 - 84,
options: [],
filterText: '',
params: {
size: 10,
current: 1,
total: 0,
keyword: ''
},
defaultExpandedKey:[],
userTableData: [],
tableLoading: false,
multipleSelection: [],
currentRow: {}
}
},
created() {},
mounted(){
this.getTreeData()
this.queryTableList(true)
},
beforeDestroy() {
this.filterText = ''
this.params = {
size: 10,
current: 1,
total: 0,
keyword: ''
}
},
methods: {
getTreeData() {
this[this.getTreeUrl]({ orgId: this.getUserInfo().orgId }).then(res => {
window.console.log(res)
this.options = [...res]
})
},
// 获取用户信息
getUserInfo() {
return JSON.parse(window.localStorage.getItem("userInfo")) || {};
},
handleSelectionChange(val) {
this.multipleSelection = val;
this.$emit('checkValue', this.multipleSelection)
},
filterNode(value, data) {
window.console.log(value, data)
if (!value) return true;
return data[this.treeProps.label].indexOf(value) !== -1 || (data['porgName'] && data['porgName'].indexOf(value) !== -1);
},
// 判断是否可以勾选
selectable(row) {
if (this.multipleSelection.length < 1 || this.multipleSelection[0].userId === row.userId) {
return true;
} else {
return false;
}
},
// 多选表格
toggleSelection(v = []) {
// window.console.log(this.$refs['multipleTable'], v)
if (v.length !== 0) {
v.forEach((item) => {
this.$refs["multipleTable"].toggleRowSelection(
this.userTableData.find((item_1) => {
return item.userId === item_1.userId;
}),
true
);
});
} else {
this.$refs["multipleTable"].clearSelection();
}
},
// 切换选项
handleNodeClick(node, obj){
// window.console.log(node,obj)
if(obj.level === 1) return false
this.currentRow = node
this.queryTableList(true)
},
// 查询表格内容
queryTableList(reset) {
if (reset) {
this.setPages();
}
let params = {
...this.params,
orgId: this.currentRow.orgId || this.getUserInfo().orgId || '',
positionId: this.currentRow.positionId || ''
};
this.userTableData = [];
this.tableLoading = true;
this[this.getTableUrl](params)
.then((rs) => {
// window.console.log(rs)
if (rs) {
this.userTableData = rs.rows;
this.setPages(rs.current, rs.size, rs.records);
} else {
this.setPages();
}
})
.finally(() => {
this.tableLoading = false;
});
},
// 设置页码
setPages(current = 1, size = 10, total = 0) {
this.params["size"] = size;
this.params["current"] = current;
this.params["total"] = total;
},
// 翻页组件方法
handleSizeChange(val) {
// window.console.log(`每页 ${val} 条`);
this.params.size = val;
this.queryTableList();
},
handleCurrentChange(val) {
// window.console.log(`当前页: ${val}`);
this.params.current = val;
this.queryTableList();
},
},
}
</script>
<style scoped lang="scss">
/deep/ {
.el-table__cell {
border-left: 1px solid rgba(204, 204, 204, 1);
border-right: -1px solid rgba(204, 204, 204, 1);
.tableFile {
line-height: 20px;
cursor: pointer;
color: #666;
transition: all 0.3s;
&:hover {
color: #66b9ff;
}
}
}
// 覆盖element表格背景
.el-table {
border: 1px solid rgba(187, 187, 187, 1);
background: rgba(255, 255, 255, 0.8);
.el-table__body-wrapper {
height: calc(100% - 42px);
}
tr {
// background: rgba(34, 81, 156, 1.0);
// background: rgba(188, 228, 249, 0.8);
background: rgba(67, 137, 249, 0.1);
.el-table__cell {
padding: 0 0!important;
}
// 修改字体
td {
.cell {
color: #333;
font-size: 10px;
font-weight: 500;
}
}
th {
.cell {
font-family: MicrosoftYaHei-Bold;
font-size: 12px;
color: #666;
font-weight: 700;
padding: 6px 0;
}
}
}
th {
background: rgba(0, 0, 0, 0);
}
.warning-row {
background: rgba(71, 42, 77, 0.7) !important;
}
.el-table__body {
tr {
height: 40px;
background: rgba(255, 255, 255, 0.8);
position: relative;
padding: 5px 0;
margin: 10px 0;
}
}
}
// 修改框线
.el-table td,
.building-top .el-table th.is-leaf {
padding: 5px 0;
// border-top: 2px solid rgba(0, 0, 0, 1.0);
border-bottom: 1px solid rgba(204, 204, 204, 1);
}
.el-table::before {
// border-bottom: 1px solid #0065B3;
height: 0px;
}
// 设置表格头部边框
.el-table th.is-leaf {
/* 去除上边框 */
// border: none;
// border: 1px solid rgba(0, 0, 0, 1.0);
border-bottom: 1px solid rgba(204, 204, 204, 1);
}
// 修改鼠标悬浮
.el-table--enable-row-hover .el-table__body tr:hover > td {
background-color: rgba(235, 252, 255, 1);
}
// 单选高亮
.el-table__body tr.current-row > td {
background-color: rgba(235, 252, 255, 1) !important;
}
// 修改分页组件样式
.el-pagination {
margin-top: 10px;
text-align: center;
color: #fff;
// .btn-next, .btn-prev,
// .el-pager li,
// .el-select .el-input .el-input__inner,
// .el-pagination__editor.el-input .el-input__inner {
// background-color: #041338;
// color: #d3d3d3;
// border: 1px solid #2a5cb0;
// border-radius: 3px;
// }
.el-pager li:not(.disabled).active {
background-color: #4389f9;
}
.el-pagination__jump,
.el-pagination__total {
// color: #fff;
margin-left: 10px;
}
}
}
.checkDispatcher-tree {
width: 100%;
height: calc(45vh);
display: flex;
.tree_content {
width: 200px;
height: 100%;
overflow-y: auto;
}
.table_content {
width: calc(100% - 215px);
height: 45vh;
padding-left: 15px;
.selectBox {
height: 40px;
margin: 0 0 5px;
display: flex;
justify-content: space-between;
align-items: center;
/deep/ {
.el-form-item {
margin-bottom: 0px;
.el-form-item__label {
color: #333;
}
}
.el-input__inner {
background-color: #fff;
color: #888;
border: 1px solid #ccc;
border-radius: 3px;
text-align: left;
}
.el-input__icon {
height: auto !important;
color: #bbb;
}
}
}
}
}
.el-scrollbar .el-scrollbar__view .el-select-dropdown__item{
height: auto;
max-height: 274px;
padding: 0;
overflow: hidden;
overflow-y: auto;
}
.el-select-dropdown__item.selected{
font-weight: normal;
}
ul li >>>.el-tree .el-tree-node__content{
height:auto;
padding: 0 20px;
}
.el-tree-node__label{
font-weight: normal;
}
.el-tree >>>.is-current .el-tree-node__label{
color: #409EFF;
font-weight: 700;
}
.el-tree >>>.is-current .el-tree-node__children .el-tree-node__label{
color:#606266;
font-weight: normal;
}
</style>
案例较为粗浅,仅供参考!
往期内容 💨
🔥 < 今日份知识点:谈谈内存泄漏 及 在 Javascript 中 针对内存泄漏的垃圾回收机制 >
🔥 < 今日份知识点:浅述对 “ Vue 插槽 (slot) ” 的理解 以及 插槽的应用场景 >
🔥 <恢复更新进度ing:今天浅聊一下前端CSS样式 及 书写的规范 >
🔥 < 每日份知识快餐:axios是什么?如何在Vue中 封装 axios ? >