element-ui el-cascader组件,异步加载城市,数据回显默认值的小坑

以前的城市联动都是分三个select写,这次用cascader联动下拉优化一下用户体验
采用的是异步加载数据,就是点击一级加载下一级数据


data() {
    return {
      province: [{}],//这个数据是组件初始化created异步加载的数据,里面加空对象是为了el-cascader初始化没有数据报错 data=null这个原因
      addressArr: [],//绑定的数据
      is_cascader: Math.random(), //重新渲染标识key
      addressInit: false, //标记组件第一级数据开始加载没有,用于识别是不是在组件
      addressProps: {
        label: 'area_name',
        value: 'area_id',
        lazy: true,//开启异步加载
        lazyLoad(node, resolve) {
          const { value, level } = node
          getPlace({ pid: value }).then(res => {
            if (res.code === 200) {
              if (level === 2) {//level=2是因为我城市数据只能选到第三级,第二级加载第三级数据
                resolve(
                  res.data.map(item => {
                    item.leaf = 'leaf'//这个必须加,就是让组件识别是不是最后一级
                    return item
                  })
                )
              } else {
                resolve(res.data)
              }
            }
          })
        }
      }
    }
}

以上代码就是我对el-cascader初始化的代码了,现在看没什么问题,接下来是数据回显
addressArr拿到数据后,需要加载对应的树结构数据,比如,我选择广东-深圳-罗湖,那么我存的addressArr=["440000", "440300", "440303"],当我拿到这个数据后,我data里面绑定的province,需要把数据嵌套进去,比如province这个是第一级数据,也就是省份,找到id=440000这个数据,添加一个children属性名,属性值就是广东所属的所有市,也就是所有父级id=440000的数据,这个就是第二级了,深圳也在第二级里面,接着我们再继续找到深圳,同样增加children:父级id=440300的数据,这样就完成了回显所需要的数据准备了;

完成上面操作后,会有几个小坑

  1. 数据读取完成了,组件还是没有选中对应的数据,展开后还是第一级,这个时候你需要重新渲染el-cascader组件,使用v-if或者使用key都可以
  2. 避开第一个坑后,还有一个坑就是数据渲染了,展开后也选中了,但是就是没有显示在input上,这个就是leaf属性问题,需要你在最后一级,所有的数据都加上item.leaf = 'leaf'就可以了

最后贴上我城市数据处理那一步给大家参考

    // 获取市区和地区
    async getAddress() {
      // 如果省份加载未完成
      if (!this.addressInit) {
        this.addressInit = true
        await getPlace().then(res => {
          if (res.code === 200) {
            this.province = res.data
          } else {
            this.$message.error(res.msg)
          }
        })
      }
      // 获取对应市数据并插入省份的children
      getPlace({ pid: this.addressArr[0] })
        .then(res => {
          return new Promise((resolve, reject) => {
            if (res.code === 200) {
              for (let i = 0; i < this.province.length; i++) {
                const item = this.province[i]
                if (item.area_id === this.addressArr[0]) {
                  item.children = res.data
                  resolve(i)
                  break
                }
              }
            } else {
              reject()
              this.$message.error(res.msg)
            }
          })
        })
        .then(index => {
          // 获取对应区数据并插入市的children
          getPlace({ pid: this.addressArr[1] }).then(res => {
            if (res.code === 200) {
              for (let i = 0; i < this.province[index].children.length; i++) {
                const item = this.province[index].children[i]
                if (item.area_id === this.addressArr[1]) {
                  // 有个小坑,必须给最后一级加上leaf属性,不然识别不了是最后一级,所以无法选中默认值
                  item.children = res.data.map(item => {
                    item.leaf = 'leaf'
                    return item
                  })
                  // 更换联动城市联动key重新渲染组件
                  this.is_cascader = Math.random()
                  break
                }
              }
            } else {
              this.$message.error(res.msg)
            }
          })
        })
    }

你可能感兴趣的:(javascript,vue.js,element-ui)