实现el-tree 单选+过滤

112 阅读1分钟

image.png

父组件 index.vue
<template>
<el-row :gutter="20">
  <el-col :xs="9" :sm="6" :md="5" :lg="5" :xl="5">
    <tree ref="tree" @change="handleTreeNodeChange"></tree>
  </el-col>
  <el-col :xs="15" :sm="18" :md="19" :lg="19" :xl="19">
     <el-button size="mini" type="info" icon="el-icon-refresh-left" @click="resetQuery">重置</el-button>
  </el-col>
</el-row>
</template>
// 子组件中列表项选择时触发
handleTreeNodeChange(data) {
  this.query.manufacturerId = data.id;
  this.form.manufacturerName = data.name;
  this.form.manufacturerId = data.id;
  this.handleQuery();
},
// 重置按钮
resetQuery() {
  this.$refs.queryForm.resetFields();
  this.query.manufacturerId = "";
  this.handleQuery();
  this.$refs.tree.clearNodeStyles();
},
子组件tree.vue
<template>
  <div v-loading="loading">
    <div class="search-top">
      <label class="search-label">企业名称</label>
      <el-input
        class="search-input"
        placeholder="输入企业名称搜索"
        v-model.trim="filterText"
        maxlength="50"
        clearable
        show-word-limit
        size="small"
        @clear="handleClear"
      ></el-input>
    </div>

    <div class="tree-node" id="tree">
      <div v-for="node in treeData" :key="node.id">
        <div :class="['tree-node-content', node.isClick ? 'is-current' : '']" @click="handleNodeClick(node)">
          <span class="tree-node-label">
            <span class="span-label" v-if="node.name.length < 16">{{ node.name }}</span>
            <el-tooltip
              popper-class="force-orgTree-tooltip-content"
              class="item"
              effect="dark"
              :content="node.name"
              :open-delay="500"
              placement="top-start"
              v-else
            >
              <span class="span-label">{{ node.name }}</span>
            </el-tooltip>
            <em v-if="node.isRegister > 0">({{ node.isRegister }})</em>
          </span>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { cloneDeep } from "lodash-es";
import { getEnterpriseList } from '@/api/enAndProManagement/product.js';
export default {
  data() {
    return {
      // 单位名称tree 模糊查询条件
      filterText: "",
      treeData: [],
      loading: false,
      copyTreeData: [],
    };
  },
  watch: {
    filterText(val) {
      this.treeData = this.copyTreeData.filter(item => {
        if(item.name.includes(val)){
          return item;
        }
      });
    },
  },
  created() {
    this.getList();

  },
  methods: {
    getList(){
      let params = {
        name: this.filterText,
      }
      this.loading = true;
      getEnterpriseList(params).then(res => {
        if(res.code == 200){
          this.treeData = res.data.map(item => {
            item.isClick = false;
            return item;
          });
          this.copyTreeData = cloneDeep(this.treeData);
          if(this.treeData.length > 0){
            this.treeData[0].isClick = true;
            this.$emit("change", this.treeData[0]);
          }
        }
        this.loading = false;
      }).finally(()=>{
        this.loading = false;
      })
    },
    
    // 当输入框清除时,需要再默认全选下所有节点,因为默认节点为空也是默认选全部
    handleClear() {
      this.$nextTick(() => {
        if (this.defaultExpandedKeys.length) {
          this.$refs.tree.setCheckedKeys(this.defaultExpandedKeys);
        }
      });
    },

    // 对树节点进行筛选时执行的方法,返回 true 表示这个节点可以显示
    filterNode(value, data) {
      if (!value) return true;
      return data.label.indexOf(value) !== -1;
    },

    handleNodeClick(data) {
      this.treeData.map(item => {
        if(data.id == item.id){
          item.isClick = true;
        }else{
          item.isClick = false;
        }
      })
      this.$emit("change", data);
    },

    // 清除所有节点的样式
    clearNodeStyles() {
      this.treeData.map(item => item.isClick = false);
    },
  },
};
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.search-label{
  font-size: 12px;
  font-weight: normal;
  color: #3e3b3b;
  display: inline-block;
  text-align: right;
  padding-right: 5px;
}
.search-top{
  margin-bottom: 10px;
}
.search-input{
  width: 190px;
}

.tree-node{
  white-space: nowrap;
  outline: none;
  .tree-node-content{
    display: flex;
    align-items: center;
    height: 30px;
    cursor: pointer;
    padding-left: 10px;
    &:hover{
      background-color: #f5f7fa;
    }
    .tree-node-label {
      display: inline-flex;
      justify-content: flex-start;
      align-items: center;
      width: 100%;
      font-size: 14px;
      .span-label {
        display: inline-block;
        max-width: 85%;
        overflow: hidden;
        text-overflow: ellipsis;
        word-break: break-all;
      }
      em {
        font-style: normal;
        padding: 4px;
      }
    }
  }
}
.is-current{
  color: #1890ff;
  background-color: #edf6ff;
}

.treeBox li{
  font-size: 12px;
}

.force-orgTree-tooltip-content {
  width: 400px;
}
::v-deep .el-tree .is-current .tree-node-label{
  color: #1890ff;
}
</style>