11

element中的cascader其实是有动态加载次级选项的方法。
方法的原理是利用址(引用)传递,动态修改:options

var c={name: 'bob'}
var d=c
d.name = 'tom'
console.log(c)
// {name: "tom"}

http://element-cn.eleme.io/#/...

其中找到究竟需要在那层添加数据就变成一个很麻烦的问题。
怎么找了?
当然只能递归了。

图片描述

简化一下大致思路:

var a = [
  {
    value: '2',
    children: [
      {
        value: '2-1',
        children: [
          {
            value: '2-1-1',
            children: [],
          },
        ],
      },
      {
        value: '2-2',
        children: [
          {
            value: '2-2-1',
            children: [],
          },
          {
            value: '2-2-2',
            children: [
              {
                value: '2-2-2-1',
                children: [],
              },
            ],
          },
        ],
      },
    ],
  },
]
var b = ['2','2-2','2-2-1']

那么我们就需要通过b找到a所在的位置。

a[0].children[1].children[0]

{
    value: '2-2-1',
    children: [],
  },

然后再赋值:

a[0].children[1].children[0].children = [{value: '2-2-1-1',children: []}]

console.log(a)

编写function:

findRegionOption(regionOptions, regionArr) {
      if (_.isEmpty(regionArr) || _.isEmpty(regionOptions)) {
        return null
      }

      let regionId = _.first(regionArr)
      let regionOption = _.find(regionOptions, regionOption => {
        return regionOption.value === regionId
      })
      
      if (!regionOption) {
        return null
      }
      
      let tailRegionArr = _.tail(regionArr) // lodash的tail方法,获取除了array数组第一个元素以外的全部元素。

      if (_.isEmpty(tailRegionArr)) {
        return regionOption
      }
      return this.findRegionOption(regionOption.children, tailRegionArr)
}

动态加载数据:

loadRegionChild(regionIdArr) {
  let regionOptions = this.regionHiera
  let regionOptionInUI = this.findRegionOption(regionOptions, regionIdArr)
  if (
    !regionOptionInUI ||
    !regionOptionInUI.children ||
    regionOptionInUI.children.length > 0
  ) {
    return null
  }

  let regionKey = _.last(regionIdArr)
  if (!regionKey) {
    return null
  }

  api
    .getRegionHiera(regionKey)
    .then(res => {
      regionOptionInUI.children = res.data
    })
}

整个页面代码大致就是:

<template>
  <div>
      <el-cascader :options="regionHiera" v-model="selectedRegion" change-on-select/>
  </div>
</template>

<script>
export default {
  name: 'Test',
  data() {
    return {
      selectedRegion: [],
      regionHiera: [
        { label: 'Malaysia', value: '136', children: [] },
        { label: 'Indonesia', value: '106', children: [] },
        { label: '中华人民共和国', value: '100000', children: [] },
        { label: 'United States', value: '244', children: [] },
      ],
    }
  },
  watch: {
    selectedRegion(nv) {
     this.loadRegionChild(nv)
    },
  },
   methods: {
     findRegionOption(regionOptions, regionArr) {
      if (_.isEmpty(regionArr) || _.isEmpty(regionOptions)) {
        return null
      }

      let regionId = _.first(regionArr)
      let regionOption = _.find(regionOptions, regionOption => {
        return regionOption.value === regionId
      })
      if (!regionOption) {
        return null
      }
      let tailRegionArr = _.tail(regionArr)
      if (_.isEmpty(tailRegionArr)) {
        return regionOption
      }
      return this.findRegionOption(regionOption.children, tailRegionArr)
    },
    loadRegionChild(regionIdArr) {
      let regionOptions = this.regionHiera
      let regionOptionInUI = this.findRegionOption(regionOptions, regionIdArr)
      if (
        !regionOptionInUI ||
        !regionOptionInUI.children ||
        regionOptionInUI.children.length > 0
      ) {
        return null
      }

      let regionKey = _.last(regionIdArr)
      if (!regionKey) {
        return null
      }

      api
        .getRegionHiera(regionKey)
        .then(res => {
          regionOptionInUI.children = res.data  //后台返回数据
        })
    },
   }
}
</script>

整体思路还是找到点击后的region,然后动态赋值给children。
写的有点乱,希望有帮助吧。

PS:其中用到的 _.XXX 引入的lodash的库

再附一个方吧,如果后台返回的数据不符合组件的数据类型(children、label、value),可以使用该方法。

/**
* 格式化Region数据格式
* @param []  
* @return [] // 返回清除listener方法 
*/
function transRegion(regionInfo) {
 if (!regionInfo) {
   return null;
 }

 let regionId = regionInfo.regionId;
 let regionName = regionInfo.name;
 let children = _.map(regionInfo.children, child => {
   return transRegion(child);
 });

 var res = {
   label: regionName,
   value: regionId,
   children: children
 };
 return res;
}

_小生_
2.6k 声望1.1k 粉丝

人一般不会因为做过什么而后悔,


« 上一篇
Web组件简介