Vue realizes the functions of sliding loading on the organization tree, pulling down to refresh, and lazy loading of data

foreword

In the work, you will encounter the situation of displaying tree structure data such as organization information or directories. The combination of el-select and el-tree tree controls in elementUI is a bit cumbersome and complicated. Therefore, it is generally through the personalized treeselect component to achieve the desired effect. If the amount of data is small, the component can be used directly without any changes. If the amount of data is too large, the page rendering and loading speed will be too slow. For example, a branch of a certain bank has more than 3,600 departmental and organizational information, so the data can only be loaded lazily. In addition, sliding to the top and then swiping down will refresh the data, sliding to the bottom and then swiping up will load more data, and the fuzzy search function.

text code

The first step is to create a public subcomponent BranchTreeSelect.vue

<template v-slot>
  <a-tree-select
    v-model="currentBranchNumber"
    tree-data-simple-mode
    style="width:100%"
    :dropdown-style="{maxHeight: '400px', overflow: 'auto'}"
    :tree-data="branchTreeData"
    allow-clear
    :show-search="true"
    :load-data="onLoadTreeData"
    :search-value="searchValue"
    placeholder="请选择机构或分行"
    @search="onSearch"
    @clear="clearSelect"
    @focus="focusSelect"
  />
</template>

<script>
import { getCurrentBranchAndChildrenBranchInfos, getCurrentBranchInfo } from '@/api/user'

export default {
  name: 'BranchTreeSelect',
  props: {
    branchNumber: {
      type: String
    }
  },
  data() {
    return {
      branchTreeData: [],
      searchValue: '',
      currentBranchNumber: '',
      allowSearchFlag: true
    }
  },
  watch: {
    'currentBranchNumber': {
      handler(val) {
        if (val) {
          this.$emit('setBranchNumber', this.currentBranchNumber.toString().split(':')[0])
        } else {
          this.$emit('setBranchNumber', '')
        }
      }
    }
  },
  created() {
    this.initValue(this.branchNumber) // 初始化机构树
  },
  methods: {
    initValue(val) {
      this.currentBranchNumber = val
    },
    onSearch(val) { // 可以模糊检索, 需要后端支持
      // 是否允许进行检索, 上一次检索数据还没渲染好不允许检索
      if (this.allowSearchFlag && !isNaN(parseInt(val)) && isFinite(val) && val.length > 2) { // 机构号至少3位数字时才可以检索
        this.allowSearchFlag = false
        getCurrentBranchInfo(val).then(res => {
          this.branchTreeData = []
          const treeArray = []
          res.forEach(function(item) {
            const node = {
              id: item.branchNumber,
              pId: item.upperBranch,
              value: (item.branchNumber + ':' + item.branchName),
              title: (item.branchNumber + ':' + item.branchName),
              isLeaf: item.isLeafBranch !== 'N'
            }
            treeArray.push(node)
          })
          this.branchTreeData = this.branchTreeData.concat(treeArray) // 拼接数组数据
          this.allowSearchFlag = true
        })
      }
    },
    focusSelect() { // 聚焦的时候查询数据, 机构id传空查询根机构以及根机构下直接子机构。如果branchTreeData有数据, 则不再查询后端数据。如果生成树结构数据过程中也不会查询后端数据。
      if (this.branchTreeData.join() === '' && this.allowSearchFlag) {
        getCurrentBranchAndChildrenBranchInfos('').then(res => {
          this.setTreeNode('', res)
        })
      }
    },
    clearSelect() { // 清空选中的机构, 则重新向后端查询根机构以及根机构下直接子机构
      this.branchTreeData = []
      getCurrentBranchAndChildrenBranchInfos('').then(res => {
        this.setTreeNode('', res)
      })
    },
    setTreeNode(parentId, dataList) { // 根据后端返回的结果生成树结构
      this.allowSearchFlag = false // 生成树结构的过程中不允许检索, 因为会导致数据的错漏...期待后续优化
      const treeArray = []
      dataList.forEach(function(item) {
        const node = {
          id: item.branchNumber,
          pId: parentId,
          value: (item.branchNumber + ':' + item.branchName),
          title: (item.branchNumber + ':' + item.branchName),
          isLeaf: item.isLeafBranch !== 'N'
        }
        treeArray.push(node)
      })
      const tempArr = this.branchTreeData.concat(treeArray)
      const newArr = []
      for (const i in tempArr) {
        if (!newArr.some(res => res.id === tempArr[i].id)) {
          newArr.push(tempArr[i])
        }
      }
      this.branchTreeData = newArr
      this.allowSearchFlag = true
    },
    onLoadTreeData(treeNode) { // 加载更多数据
      return new Promise(resolve => {
        const { id } = treeNode.dataRef
        setTimeout(() => {
          getCurrentBranchAndChildrenBranchInfos(id).then(res => {
            this.setTreeNode(id, res)
            resolve()
          })
        }, 300)
      })
    }
  }
}
</script>

<style scoped>

</style>

The second step is to call the public child component in the parent component

<branch-tree-select :branch-number="formData.branchNumber" @setBranchNumber="setBranchNumber" />

export default {
  import BranchTreeSelect from '@/components/BranchTreeSelect'
  components: {
    BranchTreeSelect
  },
  methods: {
    setBranchNumber(val) {
      // val是子组件选中值后传过来的机构号
    }
  }
}

If you have any questions, please leave a message below, I will carefully check each item and try to reply. Thanks for watching ^^

Guess you like

Origin blog.csdn.net/Damon_Cheung/article/details/128037172