el-tree 实现默认高亮最外层父节点,默认展开最外层节点

652 阅读3分钟
效果

gif-2024-03-13 at 16.42.01.gif

大致思路
大致思路
  • 对于树形组件的默认高亮:定义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>