Element-ui el-tree 异步加载 懒加载 只能选择一个同级节点

需求

树的数据是通过异步(懒)加载而来,且要求同级节点只能选择一个,一个常见的应用场景是选择住址,选择了山东省不能同时选择河北省,选择了每个节点,显示完整的从根节点到本节点的路径 。

分析

Element-ui的el-tree的选中是复选框实现,可以选择多个同级节点,如果用它自带的select api(getCheckedNodesgetCheckedKeys) 比较复杂且不可靠;因而换了一种实现思路,不用 它的select api,改为自己存储当前节点,tree组件支持node-click事件,点击node时,存储当前点击的node,只存最后一次点击的node,node对象中可以拿到父node,父node可以拿到它的父node,一级一级上去就可以到根节点。

复制代码
<el-tree
	//对应后端返回数据格式中的key字段名称
          node-key="key"
          highlight-current
          :props="treeProps"
          :load="loadChildNode"
          lazy
          @node-click="handleNodeClick()"
        />


选择地址:{{ lastClickedNodePath.map(node => node.name).join("") }}



data(){
  return {
  // 搜索住址对话框
      treeProps: {
      //对应后端返回数据格式中的name字段名称
        label: 'name',
        isLeaf: 'leaf'
      },
      //被点击节点到root的完整节点路径
     lastClickedNodePath:[]
  }   
}
//加载子节点
async loadChildNode(node, resolve) {
      console.log('加载现住址子节点回调输入参数', node, resolve)
      if (node.level === 0) {
        console.log('根节点名称', this.curZone.name)
        return resolve([{ name: this.curZone.name, key: this.curZone.key }])
      }
      const code = node.data.key
      const { data } = await getChildZonesByCode(code)  //发送请求从后端获取数据,数据格式 [{name:"",key:""}]
      // 加载村级的下一级时,子节点设置为叶子节点
      if (node.level === 2) {
        data.map(ele => {
          ele.leaf = true
        })
      }
      return resolve(data)
},
//点击节点,获取完整节点路径
handleNodeClick(data,node,component){
     this.lastClickedNodePath= this.getNodePath(node, [])
}
/**
* 获取完整的节点路径
*/
getNodePath(selectNode, nodePaths) {

 if (!nodePaths) {
   nodePaths = []
 }
 if (!selectNode.data) {
   return nodePaths
 }
 //根节点代码
 const ROOT_NODE_CODE = '0'
 if (selectNode.data.value === ROOT_NODE_CODE) {
   return nodePaths
 }
 //将元素添加到头部
 nodePaths.unshift({...selectNode.data})
 if (selectNode.parent) {
   return this.getNodePath(selectNode.parent, nodePaths)
 }
 return nodePaths
},

回显/还原初始状态

上边的地址选择是在对话框中,要求每次打开选择框,只显示根节点,没找到好办法,一个偏hack的方法是,每次打开对话框,重新渲染。

复制代码
<el-tree
 v-if="digVisible"
/>
相关推荐
我是伪码农7 分钟前
Vue 1.30
前端·javascript·vue.js
利刃大大15 分钟前
【Vue】默认插槽 && 具名插槽 && 作用域插槽
前端·javascript·vue.js
艳阳天_.18 分钟前
web 分录科目实现辅助账
开发语言·前端·javascript
2601_9498683625 分钟前
Flutter for OpenHarmony 剧本杀组队App实战04:发起组队表单实现
开发语言·javascript·flutter
风之舞_yjf26 分钟前
Vue基础(27)_脚手架安装
vue.js
kgduu41 分钟前
js之javascript API
javascript
BYSJMG1 小时前
计算机毕设选题推荐:基于大数据的癌症数据分析与可视化系统
大数据·vue.js·python·数据挖掘·数据分析·课程设计
XPii1 小时前
Photoshop应用——将图片变为油画效果
ui·photoshop
xiaoqi9221 小时前
React Native鸿蒙跨平台实现图片画廊类页面是视觉展示型APP(如摄影类、图库类、设计类APP)的核心载体,其核心需求是实现图片的流畅渲染
javascript·react native·react.js·ecmascript·harmonyos
chenhdowue1 小时前
vue3甘特图 vxe-gantt 行内显示子任务,拆分任务展示同时可拖拽调整任务日期
vue.js·甘特图·vxe-gantt