需求:根据后端返回的字典树供客户选择,还得让客户可以自定义输入名称
这是使用Vue-treeselect的异步搜索实现的,官方文档
参考文章
这里分享主要代码

			<treeselect
                ref="cbTreeselect"
                v-model="rdResultObj.reportingDwCode"
                :multiple="false"
                :normalizer="normalizer"
                :disabled="isView"
                :options="unitList"
                :backspace-removes="false"
                :load-options="iscbAsync ? loadTagsOptions : null"
                :clear-on-select="true"
                :cache-options="iscbAsync"
                :default-options="iscbAsync"
                :search-prompt-text="'请搜索'"
                :async="iscbAsync"
                placeholder="请选择呈报单位"
                @open="treeOpen()"
              >
                <label slot="option-label" slot-scope="{ node }">
                  <b v-if="node.isNew">{{ node.label }}{{ '  (新标签)' }}</b>
                  <span v-else>{{ node.label }}</span>
                </label>
            </treeselect>

iscbAsync:是用来控制tree是否使用异步搜索,主要是为了解决,回显的时候,如果只用异步搜索的话,回显值会出现unknown,一开始默认iscbAsync是false
unitList: 用来存放后端一开始返回的字典树,在回显的时候需要对回显的值匹配,如果匹配上则无须理会,若是匹配不是,则需将回显的值作为子节点push到unitList后面
loadTagsOptions:异步搜索

loadTagsOptions({ action, searchQuery, callback }) {
      // 输入时异步加载
      if (action === ASYNC_SEARCH) {
        let options = []
        const recursion = function(arr, searchQuery) {
          arr.forEach(item => {
            if (item.children && item.children.length) {
              // 满足模糊搜素则返回整个父节点联带的子节点
              if (item.title.indexOf(searchQuery) > -1) {
                options.push({
                  code: item.code,
                  title: item.title,
                  children: item.children
                })
              } else {
                // 不满足则继续往下找
                recursion(item.children, searchQuery)
              }
            } else {
              // 找到就push到数组中
              if (item.title.indexOf(searchQuery) > -1) {
                options.push(item)
              }
            }
          })
        }
        // 1. 搜索空字符串,则展示全部已有标签
        if (searchQuery.trim() === '') {
          options = [...this.unitList]
        } else {
          // 2.不为空,则生成新标签+过滤已有标签
          // 2.1 过滤已有标签
          recursion(this.unitList, searchQuery)
          // 2.2 新增标签(如果没有完全匹配到,则新增)
          if (!options.length) {
            options.push({
              code: searchQuery,
              title: searchQuery,
              isNew: true
            })
          }
        }
        // 回传
        callback(null, options)
      }
    },

treeOpen: 打开菜单的时候触发

treeOpen() {
        this.isAsync = true
    },

normalizer:

 normalizer(node) {
        if (node.children==null||node.children=='null' || node.children && !node.children.length) {
          delete node.children
        }
        return {
          id: node.code,
          label: node.title,
          children: node.children
        }
      },
Logo

前往低代码交流专区

更多推荐