ElementUI-Cascader组件同时支持懒加载和选择任意一级 问题踩坑

业务背景:

地址选择,四级联动,可选任意一级,支持懒加载,双击选择

 主要代码如下

<el-cascader
      clearable
      placeholder="请选择联系地址"
      @visible-change="visibleChange"
      class="address-cascader"
      :key="cascaderKey"
      v-model="addressIdList"
      :popper-class="popperClass"
      :props="props"
      ref="elCascader"
      @expand-change="bindEvent"
      @change="handleChange"></el-cascader>
props: {
          lazy: true,
          checkStrictly: true,
          async lazyLoad(node, resolve) {
            let nodes = []
            const {level, value} = node
            let results = []
            let parentAdminDivId = ''
            if (level === 0) {
              parentAdminDivId = ''
              nodes = await _this.getAddressInfo(adminDivList[level], parentAdminDivId)
            } else{
              // 直辖市特殊处理
              if (level === 1 && (_this.specialCityList.includes(value))) {
                nodes = [{
                  valueDesc: '市辖区',
                  valueNo: _this.zxCityInfo[node.value],
                  adminDivId: node.data.adminDivId
                }]
              } else {
                parentAdminDivId = node.data.adminDivId
                nodes = await _this.getAddressInfo(adminDivList[level], parentAdminDivId)
              }
            }
            results = nodes.map(item => ({
              label: item.valueDesc,
              value: _this.specialCityList.includes(value) ? item.valueNo : item.adminDivId,
              adminDivId: item.adminDivId,
              leaf: level >= _this.cascaderNum
            }))
            resolve(results)
          }
        }

如上图有以下问题
1. Cascader自带样式不符合需求标准

2. Cascader设计为点击单选框选择,点击右侧箭头区域加载下一级,不符合交互

3.无法双击选择

样式问题可以自定义css来覆盖,但是交互问题无法解决,翻阅很多资料博客都没有合理的解决方案

后来有天晚上有人托梦给我一个解决方案,经实测,以下方案切实可行

点击 el-cascader-node__label的时候,手动触发radio的点击事件


具体代码如下

bindEvent() {
const _this = this
this.$nextTick(() => {
let cascaderDom = document.getElementsByClassName(_this.refName)[0]
if (cascaderDom) {
setTimeout(() => {
let labelDoms = cascaderDom.querySelectorAll('.el-cascader-node .el-cascader-node__label')
let radioDoms = cascaderDom.querySelectorAll('.el-cascader-node .el-radio__inner')
if (labelDoms && labelDoms.length) {
labelDoms.forEach((item, index) => {
item.addEventListener('click', () => {
radioDoms[index].click()
})
})
labelDoms.forEach((item) => {
item.addEventListener('dblclick', () => {
_this.$refs.elCascader.dropDownVisible = false
})
})
}
}, 500)
}
})
},

核心代码如上,注:bindEvent的调用时间,每次点击出现下一级时候都要为label绑定事件,另外绑定前记得销毁

原文地址:https://www.cnblogs.com/yaokunlun/p/13679878.html