效果
大致思路
大致思路
- 对于树形组件的默认高亮:定义provincialCenterId变量用来记录后端返回的数据里的第一个节点的id值,定义treeExpandData空数组用来指定默认展开的节点id至于为什么是数组官方文档有解释在配合node-key属性以及default-expanded-keys属性和highlight-current属性就可以实现默认高亮节点了;
- 默认展开最外层父级节点:主要通过setCurrentKey方法将获取到的第一个父级节点的id传进去即可
- 关于子组件如何实时动态获取父组件中点击节点之后的最新的label值,这里主要利用 :value和@update:实现父子组件之间的通讯,然后在子组件中通过watch来进行侦听即可实现想要的效果
代码
父组件:
<div class="tree-box">
<el-input
size="mini"
style="width: 220px; margin-bottom: 10px"
placeholder="输入姓名/账号/部门进行过滤"
v-model="filterText"
clearable
suffix-icon="el-icon-search"
>
</el-input>
<p style="font-size: 14px; color: #888; padding-bottom: 10px">
当前选中的部门为:
<span style="color: #333; font-weight: 600"
>{{ currentRootInstitution }}</span
>
</p>
<el-tree
empty-text="数据为空"
class="filter-tree"
:data="data"
:props="defaultProps"
:filter-node-method="filterNode"
ref="tree"
:expand-on-click-node="false"
@node-click="handleNodeClick"
node-key="id"
:check-strictly="false"
highlight-current
:default-expanded-keys="treeExpandData"
>
<span class="span-ellipsis" slot-scope="{ node, data }">
<span style="font-size: 14px; color: #111218" :title="node.label"
>{{ node.label }}</span
>
</span>
</el-tree>
</div>
filterText: "",
data: [],
defaultProps: {
children: "children",
label: "label",
},
currentRootInstitution: "",
provincialCenterId: "",
treeExpandData: [],
created() {
this.getEquipmentList();
},
watch: {
filterText(val) {
this.$refs.tree.filter(val);
},
},
/**
* 在职人员区域逻辑
*/
// 树形控件区域逻辑
// 获取树形结构默认展开节点
getRoleTreeRootNode(provincialCenterId) {
this.treeExpandData.push(provincialCenterId);
},
// 获取数据
getEquipmentList() {
this.data = [
{
id: 1,
label: "一级 1",
children: [
{
id: 4,
label: "二级 1-1",
children: [
{
id: 9,
label:
"三级 1-1-1三级 1-1-1三级 1-1-1三级 1-1-1三级 1-1-1三级 1-1-1三级 1-1-1",
children: [
{
id: 20,
label: "四级-20",
},
],
},
{
id: 10,
label: "三级 1-1-2",
},
],
},
{
id: 44,
label: "三级",
},
{
id: 54,
label: "四级",
},
{
id: 64,
label: "五级",
},
],
},
{
id: 2,
label: "一级 2",
children: [
{
id: 5,
label: "二级 2-1",
},
{
id: 6,
label: "二级 2-2",
},
],
},
];
// 默认选中最外层父节点
this.currentRootInstitution = this.data[0].label;
//默认展开第一个节点
this.provincialCenterId = this.data[0].id;
this.getRoleTreeRootNode(this.provincialCenterId);
// 设置默认高亮项
this.$nextTick(function () {
this.$refs.tree.setCurrentKey(this.provincialCenterId);
})
},
// 筛选
filterNode(value, data) {
if (!value) return true;
return data.label.indexOf(value) !== -1;
},
// 树形节点点击事件
handleNodeClick(node, data) {
this.currentRootInstitution = node.label;
},
// 监听树形节点点击
updateCurrentRootInstitution(newValue) {
this.currentRootInstitution = newValue;
},
<!-- 抽屉--新建部门 -->
<el-drawer
size="45%"
:visible.sync="drawer2"
direction="rtl"
:before-close="(done) => done()"
:withHeader="false"
>
<OrganizationWorkDrawer3
:currentRootInstitution="currentRootInstitution"
@update:currentRootInstitution="updateCurrentRootInstitution"
/>
</el-drawer>
子组件:
<template>
<div class="add-new-department-container">
<!-- 标题 -->
<div class="drawer-header">
<h4>新建部门</h4>
<i class="el-icon-close"></i>
</div>
<!-- 内容 -->
<div class="add-new-department-box">
<el-form
:model="ruleForm"
:rules="rules"
ref="ruleForm"
label-width="80px"
>
<!-- 部门信息 -->
<div class="department-info-box">
<p class="base-info-title">部门信息</p>
<el-row :gutter="20">
<el-col :span="16">
<el-form-item label="上级部门" prop="superior_department">
<el-input
v-model="ruleForm.superior_department"
placeholder="请选择"
clearable
@focus="showDepartmentDialog"
></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="16">
<el-form-item label="部门名称" prop="department_name">
<el-input
placeholder="请输入部门名称"
v-model="ruleForm.department_name"
></el-input>
</el-form-item>
</el-col>
</el-row>
</div>
<!-- 部门设置 -->
<div class="department-set-box">
<p class="base-info-title">
部门设置 <i class="el-icon-question"></i>
</p>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="部门可见性" label-width="150px">
<el-cascader
style="width: 240px"
filterable
v-model="department_value"
:options="department_options"
@change="handleChange"
:props="{ expandTrigger: 'hover' }"
placeholder="请选择/可搜索"
clearable
></el-cascader>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="部门成员可见范围" label-width="150px">
<el-cascader
style="width: 240px"
filterable
v-model="department_value1"
:options="department_options1"
@change="handleChange1"
:props="{ expandTrigger: 'hover' }"
placeholder="请选择/可搜索"
clearable
></el-cascader>
</el-form-item>
</el-col>
</el-row>
</div>
<!-- 按钮区域 -->
<div class="btns-box">
<el-button style="width: 80px; height: 32px" @click="cancelClick">
取消
</el-button>
<el-button
style="width: 80px; height: 32px"
type="primary"
@click="submitClick"
>
确定
</el-button>
</div>
</el-form>
</div>
<!-- 部门信息 -->
<el-dialog
title="提示"
:visible.sync="isShowDialog"
width="30%"
:modal="false"
:before-close="handleClose"
>
<el-input placeholder="输入关键字进行过滤" v-model="filterText">
</el-input>
<el-tree
class="filter-tree"
:data="data"
:props="defaultProps"
default-expand-all
:filter-node-method="filterNode"
ref="tree"
@node-click="treeNodeClick"
>
</el-tree>
<span slot="footer" class="dialog-footer">
<el-button @click="isShowDialog = false">取 消</el-button>
<el-button type="primary" @click="confirmDepartmentDialog">
确 定
</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
export default {
components: {
},
props: {
currentRootInstitution: {
type: String,
default: "",
},
},
watch: {
currentRootInstitution(newVal, oldVal) {
this.ruleForm.superior_department = newVal;
// console.log('ruleForm.superior_department的值为', this.ruleForm.superior_department);
},
filterText(val) {
this.$refs.tree.filter(val);
},
},
created() {
this.ruleForm.superior_department = this.currentRootInstitution;
},
data() {
return {
// 表单数据
ruleForm: {
superior_department: "",
department_name: "",
},
rules: {
superior_department: [
{ required: true, message: "请选择上级部门", trigger: "blur" },
],
department_name: [
{ required: true, message: "请输入部门名称", trigger: "blur" },
],
},
// 部门可见性数据
department_value: ["zhinan"],
department_options: [
{
value: "zhinan",
label: "指南",
},
{
value: "ziyuan",
label: "资源",
children: [
{
value: "axure",
label: "Axure Components",
},
{
value: "sketch",
label: "Sketch Templates",
},
{
value: "jiaohu",
label: "组件交互文档",
children: [
{
value: "jiaohu1",
label: "jiaohu1 Templates",
},
],
},
],
},
],
// 部门成员可见范围数据
department_value1: ["zhinan"],
department_options1: [
{
value: "zhinan",
label: "指南",
},
{
value: "ziyuan",
label: "资源",
children: [
{
value: "axure",
label: "Axure Components",
},
{
value: "sketch",
label: "Sketch Templates",
},
{
value: "jiaohu",
label: "组件交互文档",
children: [
{
value: "jiaohu1",
label: "jiaohu1 Templates",
},
],
},
],
},
],
// 上级部门树形数据
isShowDialog: false,
filterText: "",
data: [
{
id: 1,
label: "一级 1",
children: [
{
id: 4,
label: "二级 1-1",
children: [
{
id: 9,
label: "三级 1-1-1",
},
{
id: 10,
label: "三级 1-1-2",
},
],
},
],
},
{
id: 2,
label: "一级 2",
children: [
{
id: 5,
label: "二级 2-1",
},
{
id: 6,
label: "二级 2-2",
},
],
},
{
id: 3,
label: "一级 3",
children: [
{
id: 7,
label: "二级 3-1",
},
{
id: 8,
label: "二级 3-2",
},
],
},
],
defaultProps: {
children: "children",
label: "label",
},
};
},
methods: {
/**
*
* 部门设置逻辑
*/
// 部门可见性
handleChange(value) {
console.log(value);
console.log(this.department_value);
},
// 部门成员可见范围
handleChange1(value) {
console.log(value);
console.log(this.department_value);
},
/**
* 底部按钮逻辑
*/
// 确认
submitClick() {
this.$refs.ruleForm.validate((valid) => {
if (valid) {
console.log("通过");
} else {
this.$message({
type: "error",
message: "请先完善信息",
});
return false;
}
});
},
// 取消
cancelClick() {
this.ruleForm = {
superior_department: "",
department_name: "",
};
this.department_value = ["zhinan"];
},
/**
* 新建部门逻辑
*/
filterNode(value, data) {
if (!value) return true;
return data.label.indexOf(value) !== -1;
},
treeNodeClick(val) {
this.ruleForm.superior_department = val.label;
this.$refs.ruleForm.validateField("superior_department");
this.isShowDialog = false;
},
confirmDepartmentDialog() {
this.isShowDialog = false;
},
showDepartmentDialog(index) {
this.isShowDialog = true;
this.filterText = "";
},
handleClose(done) {
done();
},
},
};
</script>
<style scoped lang="scss">
.add-new-department-container {
position: relative;
::v-deep .el-form-item--medium .el-form-item__label {
text-align: left !important;
}
p {
margin: 0;
}
.drawer-header {
border-bottom: 1px solid #eee;
height: 50px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 20px;
h4 {
margin: 0;
margin-bottom: 10px;
color: #111218;
}
}
.add-new-department-box {
padding: 20px;
.base-info-title {
padding-bottom: 6px;
text-align: left;
font-size: 16px;
color: #000;
font-weight: 600;
}
.department-info-box {
margin-bottom: 20px;
}
.department-set-box {
margin-bottom: 20px;
}
}
.btns-box {
display: flex;
align-items: center;
justify-content: center;
border-top: 1px solid #eee;
height: 50px;
margin-top: 80px;
}
}
</style>