element tree 搜索联动

在这里插入图片描述
选择框搜索+二级搜索名称

<template>
  <el-dialog
    width="65%"
    class="types"
    :modal="false"
    title="药品类别"
    :destroy-on-close="true"
    :visible="typeState"
    @close="closeTypeDialog"
    @open="open"
  >
    <el-container v-loading="typeLoading">
      <el-aside
        width="50%"
        class="classifyLeft">
        <el-container>
          <el-main>
            <div>
              <el-row :gutter="10">
                <el-col :span="12">
                  <el-select
                    v-model="searchValue"
                    size="mini"
                    style="width: 100%"
                    clearable
                    placeholder="请选择"
                    @change="handleSearch"
                  >
                    <el-option
                      v-for="item in options"
                      :key="item.value"
                      :label="item.label"
                      :value="item.value"
                    />
                  </el-select>
                </el-col>
                <el-col :span="12">
                  <el-autocomplete
                    v-model="value"
                    size="mini"
                    style="width: 100%"
                    :fetch-suggestions="querySearchAsync"
                    placeholder="请输入内容"
                    @select="handleSelect"
                  />
                </el-col>
              </el-row>
            </div>
            <div style="height: 70%">
              <el-tree
                ref="tree"
                class="tree"
                highlight-current
                :expand-on-click-node="false"
                :data="treeData"
                :props="defaultProps"
                :default-expanded-keys="defaultShowNodes"
                :filter-node-method="filterNode"
                node-key="id"
                @node-click="handleNodeClick"
              />
              <!-- :default-expanded-keys='' -->
            </div>
          </el-main>
        </el-container>
      </el-aside>
      <el-main style="padding-left: 10px !important">
        <el-container style="height: 300px">
          <el-header style="height: 20px">
            <label> 已添加: </label>
            <span
              style="float: right; font-size: 20px"
            >{
   
   { checkList.length }}条</span
            >
          </el-header>

          <el-main class="classifyTag">
            <el-tag
              v-for="tag in checkList"
              :key="tag.id"
              :disable-transitions="false"
              size="medium"
              closable
              @close="removeTag(tag)"
            >
              {
   
   { tag.label }}
            </el-tag>
          </el-main>
        </el-container>
      </el-main>
    </el-container>
    <span
      slot="footer"
      class="dialog-footer">
      <el-button
        size="mini"
        @click.stop="closeTypeDialog">取 消</el-button>
      <el-button
        type="primary"
        size="mini"
        @click.stop="searchType"
      >确 定</el-button
      >
    </span>
  </el-dialog>
</template>

<style lang="scss" scoped>
.tree {
    
    
  margin-top: 10px;
  height: 500px;
  overflow: auto;
}
::v-deep.types {
    
    
  .el-dialog__body {
    
    
    height: 60vh !important;
  }
  .el-dialog__header {
    
    
    padding: 7px;
    background-color: #33adff;
    .el-dialog__headerbtn {
    
    
      top: 10px;
    }
    .el-dialog__title {
    
    
      color: #fff;
      font-size: 14px;
    }
    .el-dialog__headerbtn .el-dialog__close {
    
    
      color: #fff;
      margin-top: -10px;
    }
  }
}
#classifyTree ::v-deep .el-scrollbar__bar {
    
    
  right: 0 !important;
}
.classifyLeft {
    
    
  height: 100%;
  padding-right: 10px;
  border-right: 1px solid #ebeef5;
}
.classifyTag {
    
    
  height: 100%;
  width: 100%;
  // margin: 10px 0 !important;
}
.classifyTag ::v-deep .el-tag {
    
    
  width: 100%;
  margin-bottom: 5px;
  position: relative;
}
.classifyTag ::v-deep .el-tag__close {
    
    
  position: absolute;
  top: 6px;
  right: 10px;
}
::v-deep.type .el-textarea__inner {
    
    
  color: #000;
}
::v-deep.el-tree--highlight-current
  .el-tree-node.is-current
  > .el-tree-node__content {
    
    
  background-color: #409eff;
}
</style>

import {
    
     queryAllTree } from '@api/common_info.js';
export default {
    
    
  props: {
    
    
    typeState: {
    
    
      type: Boolean,
      default: false
    },
    checkList: {
    
    
      type: Array,
      default: () => []
    }
  },
  data () {
    
    
    return {
    
    
      // 已选中的id数组
      typeLoading: false,
      treeData: [],
      allTreeData: [],
      defaultProps: {
    
    
        children: 'children',
        label: 'label',
        value: 'label'
      },
      typeIdArry: [],
      value: '',
      searchValue: '',
      options: [],
      defaultShowNodes: []
    };
  },
  watch: {
    
    
    value (val) {
    
    
      this.$refs.tree.filter(val);
    },
    treeData: {
    
    
      handler () {
    
    
        this.treeData.forEach((item) => {
    
    
          this.defaultShowNodes.push(item.id);
        });
      },
      deep: true
    }
    // searchValue (val) {
    
    
    //   this.$refs.tree.filter(val);
    //   this.handleNodeClick(val);
    // }
  },
  methods: {
    
    
    // 树扁平化
    treeToFlat (treeList, flatList) {
    
    
      // flatList.length > 9999 是考虑底线保护原则,出于极限保护的目的设置的,可不设或按需设置。
      if (flatList.length > 9999) {
    
    
        return;
      }

      // eslint-disable-next-line array-callback-return
      treeList.map((e) => {
    
    
        e.value = e.label;
        flatList.push(e);

        // 递归:有条件的自己调用自己,条件是 e.children.length 为真
        if (e.children && e.children.length) {
    
    
          this.treeToFlat(e.children, flatList);
        }
      });

      // console.log('扁平化后:', flatList)
      return flatList;
    },
    // 选择树
    handleSearch (val) {
    
    
      console.log(val);
      // 选择全部或清空树把树赋值给根节点
      if (!val || val === '6f06879f-dc48-11ea-a132-6c92bf99a3a6') {
    
    
        this.treeData = JSON.parse(JSON.stringify(this.allTreeData));
      } else {
    
    
        // 选择其他项加选中;
        this.treeData = this.allTreeData[0].children.filter((item) => {
    
    
          return item.id === val;
        });
      }
      this.$nextTick(() => {
    
    
        // selectId:绑定的 node-key
        this.handleNodeClick(this.treeData[0]);
        this.$refs.tree.setCurrentKey(this.treeData[0].id);

      });
      this.$forceUpdate();
    },
    // 树可搜索 watch判断
    filterNode (value, data) {
    
    
      console.log(value, data);
      if (!value) return true;
      return data.label.indexOf(value) !== -1;
    },
    // 级联搜索
    querySearchAsync (queryString, cb) {
    
    
      let treeArray = [];
      treeArray = this.treeToFlat(this.treeData, treeArray);
      const results = queryString ? treeArray.filter(this.createFilter(queryString)) : treeArray;
      // 调用 callback 返回建议列表的数据
      console.log(results);
      cb(results);
    },
    createFilter (queryString) {
    
    
      return (treeArray) => {
    
    
        return treeArray.label.indexOf(queryString) === 0;
      };
    },
    // 级联选择
    handleSelect (val) {
    
    
      console.log(val);
      this.handleNodeClick(val);
      this.$nextTick(() => {
    
    
        // selectId:绑定的 node-key
        this.$refs.tree.setCurrentKey(val.id);
      });
    },
    // 初始化
    open () {
    
    
      this.typeLoading = true;
      queryAllTree({
    
     sysTag: 'kb', type: 4 }).
        then((result) => {
    
    
          const arr = result.data.data[0];
          this.allTreeData.push(arr);
          this.treeData = JSON.parse(JSON.stringify(this.allTreeData));
          this.options = this.allTreeData[0].children.map((item) => {
    
    
            return {
    
    
              id: item.id,
              label: item.label,
              value: item.id
            };
          });
          this.options.unshift({
    
    
            id: '6f06879f-dc48-11ea-a132-6c92bf99a3a6',
            label: '全部',
            value: '6f06879f-dc48-11ea-a132-6c92bf99a3a6'
          });
          this.$nextTick(() => {
    
    
            // selectId:绑定的 node-key
            this.$refs.tree.setCurrentKey(this.treeData[0].id);
          });
          this.typeLoading = false;
        }).
        catch((err) => {
    
    
          console.log(err);
        });
    },
    // 移除
    removeTag (tag) {
    
    
      this.typeIdArry.filter((i) => i !== tag.id);
      this.checkList.splice(this.checkList.indexOf(tag), 1);
    },
    // 点击树
    handleNodeClick (data) {
    
    
      console.log(data);
      const {
    
     id, label } = data;
      const tmp = this.checkList.find((x) => x.id === id);
      if (!tmp && label !== '全部') {
    
    
        this.checkList.push({
    
    
          label,
          id
        });
      }
    },
    // 确定
    searchType () {
    
    
      this.typeIdArry = [];
      this.typeIdArry = this.checkList.map((i) => i.label);
      const finalArr = [];
      this.typeIdArry.forEach((item) => {
    
    
        finalArr.push(this.findPatentValue(this.allTreeData[0].children, item, 'label', 'children').join('->'));
      });
      console.log(finalArr);


      this.$emit('searchType', finalArr.join('\n'));
    },
    recursiveFilter (arr, v, result) {
    
    
      arr.forEach((item) => {
    
    
        if (item.id === v) {
    
    
          result.push(item);
        } else if (item.children.length > 0) {
    
    
          this.recursiveFilter(item.children, v, result);
        }
      });
    },
    //查找子节点所有的父节点
    findPatentValue (array, targetId, valueKey, childrenKey) {
    
    
      if (!targetId || !Array.isArray(array)) return [];
      const result = [];
      let valid = false;
      const seek = (_array, _targetId) => {
    
    
        let parentValue = '';
        const up = (_array_, _targetId_, lastValue) => {
    
    
          _array_.forEach((v) => {
    
    
            const val = v[valueKey];
            const child = v[childrenKey];
            if (val === _targetId_) {
    
    
              valid = true;
              parentValue = lastValue;
              return;
            }
                child?.length && up(child, _targetId_, val);
          });
        };
        up(_array, _targetId);
        if (parentValue) {
    
    
          result.unshift(parentValue);
          seek(_array, parentValue);
        }
      };
      seek(array, targetId);
      return valid ? [...result, targetId] : [];
    },
    // 关闭
    closeTypeDialog () {
    
    
      this.treeData = [];
      this.allTreeData = [];
      this.value = '';
      this.searchValue = '';
      this.$emit('closeDialog', {
    
     typeIdArr: this.typeIdArry });
    }
  }
};

猜你喜欢

转载自blog.csdn.net/qq_22167557/article/details/127210156