用mint-ui picker组件 实现省市区三级联动

本文介绍如何使用Mint-UI的picker和popup组件实现省市区三级联动效果,包括组件配置、数据加载及缓存策略,解决change事件多发请求及取消时数据回滚问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

公司上一期项目中新增了省市区滑动三级联动效果,用的是mint-ui的picker组件和popup组件,效果如下:点击确定换地区,点击取消不变

省市区数据是后台给的(根据上一级的id,获取下一级数据列表,省列表传0),数据格式如下

接下来就直接上代码了

引入组件后的html部分

<mt-pop v-model="popupVisible" position="bottom" class="prop-tk">
   <div class="clR pop-btn clearfix">
      <p @click="cancle">取消</p>
      <p @click="sureMap">确定</p>
   </div>
   <mt-picker ref="pickCom" :slots="slots" @change="onValuesChange" value-key="areaName"></mt-picker> 
</mt-pop>

data里的slots数据和mint-ui格式一样

slots:[
                    {
                        flex: 1,
                        defaultIndex: 0,
                        values:[],
                        className: 'slot1',
                        textAlign: 'center',
                    }, {
                        pider: true,
                        content: '-',
                        // className: 'slot2'
                    }, {
                        flex: 1,
                        values:[],
                        className: 'slot3',
                        textAlign: 'center'
                    }, {
                        pider: true,
                        content: '-',
                        // className: 'slot4'
                    }, {
                        flex: 1,
                        values: [],
                        className: 'slot5',
                        textAlign: 'center'
                    }
                ],

页面加载时获取省市区数据(默认省和市是上个页面带过来的)

            this.$nextTick(() => { 
                // 获取省数据
                _this.getPrevenceData(0).then(res=>{
                    _this.slots[0].values = res;
                    // 根据默认省获取要显示的省
                    res.forEach((item,index)=>{
                                          // 上个页面传过来的省  
                        if(item.areaName == _this.mrProvience){
                            _this.mrpId = item.id;
                            _this.slots[0].defaultIndex= index;
                            // 获取市数据
                            var cityList = _this.getPrevenceData(item.id);
                            // 根据默认市获取要显示的市
                            cityList.then(rescity =>{
                                // 给数据做缓存取消时用
                                _this.oldCityList =rescity;
                                _this.slots[2].values = rescity;
                                rescity.forEach((item,index)=>{
                                    if(item.areaName == _this.showCity){
                                        // 缓存id如果滑动时id变化才发请求
                                        _this.mrcid = item.id;
                                        _this.slots[2].defaultIndex= index;
                                        // 获取区的数据
                                        var quList = _this.getPrevenceData(item.id);
                                        quList.then(resqu =>{
                                            _this.oldQuList = resqu;
                                            _this.slots[4].values = resqu;
                                            _this.cityDataReady = true;
                                            var valueArr = this.$refs.pickCom.getValues()
                                            this.oldSlots = valueArr.concat();
                                        })
                                    }
                                })
                            })
                        }
                    })
                })

城市滑动变化触发picker组件的change事件(id变化才发对应请求,否则会多次发请求)

onValuesChange(picker,values){
                //判断如果省的id变化了,就去请求市和区,否则只请求区
                if(this.cityDataReady){
                    //当省变化的时候,请求市和区
                    if(this.mrpId != values[0].id){
                        //请求市
                         this.getPrevenceData(values[0].id).then(res =>{
                            picker.setSlotValues(2,res);
                            this.mrpId = values[0].id;
                            this.mrcid = values[2].id;
                        })
                    }   
                    //当市变化的时候,请求区
                    if(this.mrcid !=values[2].id){
                        //请求区,当仅仅是区变化的时候,不需要发任何请求
                         this.getPrevenceData(values[2].id).then(res =>{
                            picker.setSlotValues(4,res);
                            this.mrpId = values[0].id;
                            this.mrcid = values[2].id;
                        })
                    }
                }
                
            },

点击确定缓存当前数据

sureMap(){
  this.popupVisible = false;
  // 获取变换后的城市数据
  var valueArr = this.$refs.pickCom.getValues()
  this.oldSlots = valueArr.concat();
  this.oldCityList = this.$refs.pickCom.getSlotValues(2);
  this.oldQuList = this.$refs.pickCom.getSlotValues(4)
},

点击取消时把缓存的数据赋值给picker组件

cancle(){
   _this.popupVisible = false;
  // 把缓存的数据赋值给对应的slot _this.$refs.pickCom.setSlotValues(2,_this.oldCityList); _this.$refs.pickCom.setSlotValues(4,_this.oldQuList); _this.$refs.pickCom.setValues(this.oldSlots); }

在做这个功能时出现的问题主要有2个,一个是change时多发请求问题,第二个就是取消时还要回到原来的数据(因为组件默认change之后自动就变了)

还好后来问题都解决了

转载于:https://www.cnblogs.com/zpxm/p/8670960.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值