最近小程序改版,页面多出来一个城市选择的功能,UI就给了一个设计图,作为前端的我,有点“懵”,往往的城市选择都是3级联动的picker插件,小程序也直接用picker就行了,这是让我咋搞?
然后UI说了句:‘省选择之后,出现地级市,地级市完了就显示区县......’。

【省/市/县】微信小程序自定义城市选择三级联动功能实现!-QUI-Notes

插件原理分析:

分析:这个城市选择的功能依旧是三级联动的效果,只不过再用picker就不合适了,从新自定义一个小插件,它不香嘛?

  1. 1.一个底部弹框触发事件,通过一个 参数:zoneFlag 控制弹框显示隐藏;
  2. 2.预设三个参数,分别用来存储选择后的 省份、地级市和县区,默认为空;
  3. 3.预设一个参数,控制插件当前显示的层级和所需要显示的内容;
  4. 4.预设三个数组,分别存储全国的省份、地级市和县区;
  5. 5.点击组件,将点击的数据同步到选择的参数。这里需要一个点击事件,由于三个选择区域是分开的,所以最好写3个事件分别控制所选择的事件,将结果绑给对应的参数,然后触发下一个层级,让下一个层级显示出来!

实现效果:

【省/市/县】微信小程序自定义城市选择三级联动功能实现!-QUI-Notes

具体代码:

1.弹框触发事件

<!-- 地区筛选弹框触发事件 -->
<view class="zone-box flex aic jcc" bindtap="zoneSel">
              <ui-font size="14">{{selSheng?selSheng:'默认省份'}}</ui-font>
              <image src="/images/icon/icon_dot.png"></image>
</view>
<!-- 地区筛选弹框 -->
 <view class="qui-boom" wx:if="{{zoneFlag}}" bindtap="closeZoneModle">
    <view class="qui-boom-bottom login-modle" catchtap="stop">
   <!-- 弹框内容填充区 -->
   </view>
</view>

 2.三级联动部分

<view class="padding">
            <view class="zone-m-result padding-t20 padding-b ui-size-14">
              <text class="{{zonecur==0?'active':'cor33'}}">{{selSheng?selSheng:'选择省份'}}</text>
              <text class="{{zonecur==1?'active':'cor33'}}">{{selShi?selShi:'选择地市'}}</text>
              <text class="{{zonecur==2?'active':'cor33'}}">{{selXian?selXian:'选择县区'}}</text>
            </view>
            <block wx:if="{{zonecur==0}}">
                <view class="zone-m-city" >
                  <block wx:for="{{zoneS}}" wx:key="index">
                    <text data-index="{{index}}" bindtap="chooseS">{{item.title}}</text>
                  </block>
                </view>
            </block>
            <block wx:if="{{zonecur==1}}">
                <view class="zone-m-city" >
                  <block wx:for="{{zoneD}}" wx:key="index">
                    <text  data-index="{{index}}" bindtap="chooseD">{{item.title}}</text>
                  </block>
                </view>
            </block>
            <block wx:if="{{zonecur==2}}">
                <view class="zone-m-city">
                  <block wx:for="{{zoneC}}" wx:key="index">
                    <text  data-index="{{index}}" bindtap="chooseC">{{item.title}}</text>
                  </block>
                </view>
            </block>
        </view>

完整代码:

<!-- 地区切换 -->
  <view class="ms-zone padding-b">
    <ui-row>
        <ui-span span="3"> 
            <view class="zone-box flex aic jcc" bindtap="zoneSel">
              <ui-font size="14">{{selSheng?selSheng:'默认省份'}}</ui-font>
              <image src="/images/icon/icon_dot.png"></image>
            </view>
        </ui-span>
        <ui-span span="3"> 
           <view class="zone-box flex aic jcc" bindtap="zoneSel">
              <ui-font size="14">{{selShi?selShi:'默认地市'}}</ui-font>
              <image src="/images/icon/icon_dot.png"></image>
            </view>
        </ui-span>
        <ui-span span="3"> 
          <view class="zone-box flex aic jcc" bindtap="zoneSel">
              <ui-font size="14">{{selXian?selXian:'默认县区'}}</ui-font>
              <image src="/images/icon/icon_dot.png"></image>
            </view>
        </ui-span>
    </ui-row>
  </view>
  <!-- 地区筛选弹框 -->
  <view class="qui-boom" wx:if="{{zoneFlag}}" bindtap="closeZoneModle">
    <view class="qui-boom-bottom login-modle" catchtap="stop">
        <view class="login-line"></view>
        <view class="padding">
            <view class="zone-m-result padding-t20 padding-b ui-size-14">
              <text class="{{zonecur==0?'active':'cor33'}}">{{selSheng?selSheng:'选择省份'}}</text>
              <text class="{{zonecur==1?'active':'cor33'}}">{{selShi?selShi:'选择地市'}}</text>
              <text class="{{zonecur==2?'active':'cor33'}}">{{selXian?selXian:'选择县区'}}</text>
            </view>
            <block wx:if="{{zonecur==0}}">
                <view class="zone-m-city" >
                  <block wx:for="{{zoneS}}" wx:key="index">
                    <text data-index="{{index}}" bindtap="chooseS">{{item.title}}</text>
                  </block>
                </view>
            </block>
            <block wx:if="{{zonecur==1}}">
                <view class="zone-m-city" >
                  <block wx:for="{{zoneD}}" wx:key="index">
                    <text  data-index="{{index}}" bindtap="chooseD">{{item.title}}</text>
                  </block>
                </view>
            </block>
            <block wx:if="{{zonecur==2}}">
                <view class="zone-m-city">
                  <block wx:for="{{zoneC}}" wx:key="index">
                    <text  data-index="{{index}}" bindtap="chooseC">{{item.title}}</text>
                  </block>
                </view>
            </block>
        </view>
    </view>
  </view>

js:

Page({
  data: {
 zoneFlag:false,
    zonecur:0,
    selSheng:'',
    selShi:'',
    selXian:'',
    zoneS:[
      {title:'北京'},
      {title:'上海'},
      {title:'天津'},
      {title:'重庆'},
      {title:'河北'},
      {title:'河南'},
      {title:'广东'},
      {title:'广西'},
      {title:'云南'},
      {title:'河南'},
      {title:'河南'},
      {title:'广东'},
      {title:'广西'},
      {title:'云南'},
      {title:'河南'},
      {title:'广东'},
      {title:'广西'},
      {title:'云南'},
    ],
    zoneD:[
      {title:'郑州'},
      {title:'开封'},
      {title:'洛阳'},
      {title:'新郑'},
      {title:'新乡'},
      {title:'许昌'},
      {title:'鹤壁'},
      {title:'平顶山'},
      {title:'三门峡'},
      {title:'濮阳'},
      {title:'焦作'},
      {title:'信阳'},
      {title:'周口'},
      {title:'漯河'},
      {title:'商丘'},
      {title:'南阳'},
    ],
    zoneC:[ 
      {title:'二七区'},
      {title:'中原区'},
      {title:'惠济区'},
      {title:'金水区'},
      {title:'郑东新区'},
      {title:'机场新区'},
      {title:'平原新区'},
      {title:'高新区'},
      {title:'荥阳'},
      {title:'上街'},
      {title:'登封'},
    ],
},
  zoneSel(){
    this.setData({
      zoneFlag:true
    })
  },
  chooseS(e){
    let i = e.currentTarget.dataset.index;
    let res = this.data.zoneS[i].title;
    this.setData({
      selSheng: res,
      zonecur:1
    })
  },
  chooseD(e){
    let i = e.currentTarget.dataset.index;
    let res = this.data.zoneD[i].title;
    this.setData({
      selShi: res,
      zonecur:2
    })
  },
  chooseC(e){
    let i = e.currentTarget.dataset.index;
    let res = this.data.zoneC[i].title;
    this.setData({
      selXian: res,
      zonecur:0,
      zoneFlag:false
    })
  },
closeZoneModle(){
    this.setData({
      zoneFlag:false
    })
  },
stop:function(){ //不可删除  
},
})

这样就完成了一个三级联动的城市选择插件,关于css部分,过于简单就不复制了,注意是理解原理,才能更快的找到“解题办法”。觉得不错,点个赞、打个赏都可以!