先贴插件地址及代码  https://vue-treeselect.js.org/

<treeselect
  :multiple="true"
  :options="options"
  :load-options="loadOptions"
  placeholder="Try expanding any folder option..."
  v-model="value"
  />
import { LOAD_CHILDREN_OPTIONS } from '@riophae/vue-treeselect'

// We just use `setTimeout()` here to simulate an async operation
// instead of requesting a real API server for demo purpose.
const simulateAsyncOperation = fn => {
  setTimeout(fn, 2000)
}

export default {
  data: () => ({
    value: null,
    options: [ {
      id: 'success',
      label: 'With children',
      // Declare an unloaded branch node.
      children: null,
    }, {
      id: 'no-children',
      label: 'With no children',
      children: null,
    }, {
      id: 'failure',
      label: 'Demonstrates error handling',
      children: null,
    } ],
  }),

  methods: {
    loadOptions({ action, parentNode, callback }) {
      // Typically, do the AJAX stuff here.
      // Once the server has responded,
      // assign children options to the parent node & call the callback.

      if (action === LOAD_CHILDREN_OPTIONS) {
        switch (parentNode.id) {
        case 'success': {
          simulateAsyncOperation(() => {
            parentNode.children = [ {
              id: 'child',
              label: 'Child option',
            } ]
            callback()
          })
          break
        }
        case 'no-children': {
          simulateAsyncOperation(() => {
            parentNode.children = []
            callback()
          })
          break
        }
        case 'failure': {
          simulateAsyncOperation(() => {
            callback(new Error('Failed to load options: network error.'))
          })
          break
        }
        default: /* empty */
        }
      }
    },
  },
}

插件引入方式不再赘述

下面开始叙述懒加载:

插件判断当前文本是否可以展开的依据是改层级是否存在"children"字段, 也就是说如果展开到某一级别不想再次展开需要将改层级的"children"删除(可以和后端沟通, 没有下一级就不给带children字段, 自己删除也可以, 代码如下)

data.forEach(element => {
  element['id'] = element.sg001 + 'sg' // 防止id混淆
  element['label'] = element.sg008
  delete element.children // 删除children字段, 防止出现树形展开结构(treeselect根据当前对象内部有无children字段确定是否需要展开下级菜单)
})

现在来说级联

HTML代码

<treeselect v-model="issuePointValue" :load-options="loadOptions" :multiple="true" :clearable="false" :options="issuePoint" @select="addCheckPoint" @deselect="removeCheckPoint" placeholder="问题点" />

v-model="issuePointValue"  // 绑定数据

:load-options="loadOptions" // 展开触发时间, 在此方法内调级联接口

:options="issuePoint" // 下拉展示数据

@select="addCheckPoint" // 勾选触发方法

@deselect="removeCheckPoint" // 取消勾选触发方法

// 问题点动态加载
      loadOptions ({
        action,
        parentNode,
        callback
      }) {
        if (action === LOAD_CHILDREN_OPTIONS) {
          if (parentNode.sd001 && !parentNode.sg001) { // 加载二级, 二级菜单无sg001
            simulateAsyncOperation(() => {
              listReserveByAdminRegion({
                'data': {
                  'sd001': parentNode.sd001
                }
              }).then(res => {
                if (res.status === 1000) {
                  let data = res.data
                  data.forEach(element => {
                    element['id'] = element.sg001 + 'b' // 防止id混淆
                    element['label'] = element.sg008
                  })
                  parentNode.children = data
                }
              })
              callback()
            })
          } else if (!parentNode.sd001 && parentNode.sg001) { // 加载三级, 三级sd001为null
            simulateAsyncOperation(() => {
              listCheckPointToView({
                'data': {
                  'sg001': parentNode.sg001
                }
              }).then(res => {
                if (res.status === 1000) {
                  let data = res.data
                  data.forEach(element => {
                    element['id'] = element.cd001 + 'c' // 防止id混淆
                    element['label'] = element.cd004
                  })
                  parentNode.children = data
                }
              })
              callback()
            })
          }
        }
        // parentNode.children = []
        // callback(new Error('Failed to load options: network error.'))
      },

此处"loadOptions"方法只要展开级联数据就会调用, 所有级别数据都生效,相当于内部做好了一个递归, 知道没有children字段才停止调用, 这就是上面要删除children的原因

因此需要做一个判断现在处于第几级, 来确定调用哪个接口, 我上面是根据不同接口返回不同字段进行判断

下面是做在没有展开的情况下, 也就是说只有一级父节点并勾选的情况下, 要请求其下的所有子节点并执行勾选方法

// 问题点选中
      async addCheckPoint (node) {
        if (node.id === (node.sd001 + 'a')) {
          await listReserveByAdminRegion({
            'data': {
              'sd001': node.sd001
            }
          }).then(res => {
            if (res.status === 1000) {
              let data = res.data
              data.forEach(element => {
                element['id'] = element.sg001 + 'b' // 防止id混淆
                element['label'] = element.sg008
              })
              node.children = data
              node.children.forEach(element => {
                this.addCheckPoint(element)
              })
            }
          })
        } else if (node.id === (node.sg001 + 'b')) {
          await listCheckPointToView({
            'data': {
              'sg001': node.sg001
            }
          }).then(res => {
            if (res.status === 1000) {
              let data = res.data
              data.forEach(element => {
                element['id'] = element.cd001 + 'c' // 防止id混淆
                element['label'] = element.cc002
              })
              node.children = data
            }
          })

          let pointList = []
          pointList = node.children
          this.$refs.arcgisVue.addCheckPointToMap(pointList)
        } else if (node.id === (node.cd001 + 'c')) {
          let pointList = []
          pointList.push(node)
          this.$refs.arcgisVue.addCheckPointToMap(pointList)
        }
      },

这里同样要验证改调用哪一级子节点接口并对每一级结点进行方法执行

下面是取消结点, 

// 问题点取消选中
removeCheckPoint (node) {
  let data = this.formatterSelected(node)
  let pointIdList = []
  pointIdList.push(data)
  this.$refs.arcgisVue.removeCheckPointFromMap(data)
},
// 格式化代码
formatterSelected (data) {
  let a = []
  if (data.children && data.children.length > 0) {
    data.children.forEach((item, index) => {
      a.push(...this.formatterSelected(item))
    })
  } else {
    a.push({
      id: data.id,
      value: data.value
     })
   }
   return a
 }

 

Logo

前往低代码交流专区

更多推荐