Cascade in Element dynamically loads provincial / city / district data

The cascade in element is actually a way to dynamically load secondary options.
The principle of this method is to use address (Reference) transmission and dynamic modification: options.

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

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

It becomes a very troublesome problem to find out which layer of data needs to be added.
What's the matter?
Of course, recursion is the only way.

To simplify the general idea:

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']

Then we need to find the location of a through b.

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

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

Then assign:

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

console.log(a)

Write 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) // The tail method of lodash obtains all elements except the first element of array array.

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

Load data dynamically:

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 => {
      let regionHiera = res.data
      regionOptionInUI.children = regionChildrenTransfomed  // Dynamic load assignment
    })
}

The whole page code is roughly as follows:

<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: 'The People's Republic of China', 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 => {
          let regionHiera = res.data  //Background return data
          regionOptionInUI.children = regionChildrenTransfomed
        })
    },
   }
}
</script>

The overall idea is to find the region after clicking, and then dynamically assign it to children.
It's a bit messy. I hope it helps.

Keywords: Javascript

Added by zartzar on Sat, 30 Nov 2019 08:38:00 +0200