Vant Cascader省市区数据太多,点一次掉一次子级数据

背景:之前是后端把所有数据都返回(平级数据),然后前端自己写方法去处理成父子级关系来用的:js方法将省市区的平级数据转换成父子树状数据

因为之前省市区最多只有三级数据,总共不到四千条数据,所以接口返回的速度还好

最近需求是 省市区县,有四级或更多级,数据实在是太多(四万多条数据),如果后端一次性返回,速度实在是太慢,十几秒后才返回,不太行,所以就新出了个接口

解决方案:后端返回一级数据,点一下父级,掉一下接口获取子级数据

父级

vant-address 是封装组件

<template>
    <div>
        <van-button color="linear-gradient(to right, #ff6034, #ee0a24)" @click="showPop">选择地址</van-button>
        <div>选择的地址名字:{{formData.areaName}}</div>
        <div>选择的地址code:{{formData.areaCode}}</div>
        <vant-address :is-areashow="isAreaVisible" @closepop="closePop" @closecancel="closeCancel"></vant-address>
    </div>
</template>
<script>
import VantAddress from '@/路径/vant-address.vue';
export default {
    data () {
        return {
            isAreaVisible: false, // 组件是否显示
            formData: {
                areaCode: '',
                areaName: ''
            }
        }
    },
    components:{
        VantAddress
    },
    methods: {
        showPop(){
            this.isAreaVisible = !this.isAreaVisible
        },
        closePop(areaName,areaIds){
            // 点击 确定事件,获取选中的name和code,并关闭弹框
            console.log(areaName,areaIds);
            this.formData.areaCode = areaIds
            this.formData.areaName = areaName
            this.isAreaVisible = false
        },
        closeCancel(){
            // 点击 取消事件,关闭弹框
            this.isAreaVisible = false
        },

    }
};
</script>
<style scoped='scoped' lang='scss'>
</style>

子级

<!--选择位置组件-->
<template>
  <div>
    <van-popup v-model="isAreashow" round position="bottom">
      <div class="queding" @click="addressSubmit">确定</div>
      <van-cascader
        title="请选择所在地区"
        style="padding-bottom: 80px;"
        :options="options"
        v-model="cascaderValue"
        :field-names="customFieldName"
        @close="onClose"
        @change="onChangeArea"
        @finish="onFinish"
      />
    </van-popup>
  </div>
</template>
<script>

import { areaParentData } from '@/api/地址'; // 接口地址
export default {
  props: {
    isAreashow: {
      type: Boolean,
      default: false
    }
  },
  data(){
    return{
      options: [],
      isAreaVisible: false,
      customFieldName: {
        text: 'name',
        value: 'areaId',
        children: 'children',
        code: 'code'
      },
      cascaderValue: '',
      divisionIds: '',
      divisionNames: ''
    }
  },

  mounted(){
    this.getAreaList();
  },

  methods:{
    addressSubmit(){
      // 确定事件,调用父级的closepop事件,传参name和code
      this.$emit('closepop',this.divisionNames,this.divisionIds)
    },
    onClose(){
      // 取消事件,调用父级的closecancel事件
      this.$emit('closecancel')
    },
    onFinish({ selectedOptions }) {
      // 选中的内容,赋值给name和code
      this.divisionNames = selectedOptions.map(option => option.name).join('-')
      this.divisionIds = selectedOptions.map(option => option.areaId).join(',')
    },
    //获取地区数据
    async getAreaList(){
        // 后端接口,获取省市区一级数据
        const res = await areaParentData({
            parentCode: 0 // 传0是一级数据
        })
        this.ProvinceList = res.data
        this.options = [] // 先清空一下,不然会有重复数据
        res.data.forEach(item => {
          this.options.push({
            name: item.name,
            areaId: item.areaId,
            code: item.code,
            childrenStatus: item.childrenStatus, // 接口返回的是否有子级
            children: item.children || null// 这个很关键
          })
        });
    },
    onChangeArea({ value, selectedOptions, tabIndex }) {
      console.log(value, selectedOptions, tabIndex);
      // value是选中当前列的value(areaId),selectedOptions是选中的数组,tabIndex是选中数组的第几个
      // 需要后台接口返回children数据
      // 拿到数据后,动态添加
      if(selectedOptions[selectedOptions.length-1].childrenStatus){
      // 如果选中数组的最后一个的childrenStatus为true,说明它有子级,就掉接口
        areaParentData({
          parentCode: selectedOptions[selectedOptions.length-1].code // 取得是选中数组里最后一个对象的code
        }).then(res => {
          // 接口返回的数据也就是res.data 赋值给那条数据当children
          this.addTree(selectedOptions, res.data, value)
        })
      }
    },
    addTree(selectedOptions, children, id) {
      selectedOptions.forEach(item => {
        if (item.areaId === id) {
          item.children = children
        }
      })
    }
  }
}
</script>
<style lang="scss" scoped>
  .van-cascader{
    color: #323233 !important;
  }
  .queding{
    color: #fff;
    background-color: #ff4949;
    position: fixed;
    bottom: 0;
    width: 90%;
    // padding: 10px 20px;
    height: 36px;
    line-height: 36px;
    border-radius: 4px;
    font-size: 14px;
    text-align: center;
    z-index: 10;
    left: 50%;
    transform: translate(-50%, -50%);
  }
</style>

父级页面样式:

省市区组件是封装组件

我用的 vant 的 Cascader 组件,封装成一个组件了,点击确定事件和取消事件用的父子事件

因为可能选择二级就完成了,也可能选择三级、四级,所以最下面加了个确定按钮,点击确定才算完成

接口返回的第一级数据

{
  "areaId": "1", // 后面需要传给后端的id
  "parentCode": "0",
  "code": "1100001", // 掉下一级数据传给后端的code
  "name": "北京",
  "status": 0,
  "level": 0,
  "prefixCode": "B",
  "ifHot": 0,
  "logo": "/beijing.jpeg",
  "areaIdGroup": "",
  "areaNameGroup": "",
  "children": "",
  "childrenStatus": true // 是否有子级,如果是true就说明有子级,false就没有子级
},
{
  "areaId": "37",
  "parentCode": "0",
  "code": "130000",
  "name": "河北省",
  "status": 0,
  "level": 0,
  "prefixCode": "H",
  "ifHot": 0,
  "logo": "/heibei.jpg",
  "areaIdGroup": "",
  "areaNameGroup": "",
  "children": "",
  "childrenStatus": true
}

 接口返回的二级数据

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vant Cascader是一个基于Vant组件库的级联选择器组件。它可以用于选择多级数据,比如选择地区、选择分类等。引用\[2\]中的代码展示了一个使用Vant Cascader的示例,其中通过onChange方法来动态添加子选项,通过onFinish方法获取选择的结果。 在引用\[3\]中的代码中,展示了一个使用Vant Cascader的微信小程序示例。通过van-field组件和van-popup组件来实现级联选择器的展示和交互。 如果你有关于Vant Cascader的具体问题,请提供更详细的信息,我将尽力为你解答。 #### 引用[.reference_title] - *1* [vant中的Cascader 级联选择异步加载地区数据](https://blog.csdn.net/weixin_43794749/article/details/126302417)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [vant cascader级联选择器动态无限加载](https://blog.csdn.net/liubangbo/article/details/127124420)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Vant Cascader 级联选择使用 wx小程序](https://blog.csdn.net/LKX_S/article/details/129410595)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值