一、需求背景

电商系统中地区选择是比较常见、公用的一个功能,地区数据,多级联动(省、市、区、镇):

b2b2c商城原生小程序地区组件代码分享-LMLPHP b2b2c商城原生小程序地区组件代码分享-LMLPHP

本文分享了Javashop电商系统的小程序端地区选择组件的实现。

二、代码封装

首先在components文件下新建一个regionpicke文件夹, 再在该文件夹下新建Component(一个自定义组件由json,wxml,wxss,js四个文件组成) b2b2c商城原生小程序地区组件代码分享-LMLPHP

json文件中设置component字段为true (声明该文件为自定义组件)

{

"component": true

}

组件内的wxml:

<view class='area-nav'>
  <view class='choosed-area'>
    <view wx:for="{{choosedAreas}}" wx:key="index" wx:if="{{choosedAreas.length}}" class="nav-li {{item && item.region_grade === areas[0].region_grade ? 'selected':''}}" bindtap="onchangeChoosedItem" data-item="{{item}}">{{item.local_name || '请选择'}}</view>
    <view wx:if="{{!choosedAreas.length || !finished}}">请选择</view>
  </view>
</view>
<view class='main'>
  <scroll-view scroll-y="true" class='main-ul'>
    <view class="main-li {{item.selected ? 'selected':''}}" wx:for="{{areas}}" wx:key="index" bindtap='onchangeItem' data-item="{{item}}">
      <text class='item'>{{item.local_name}}</text>
      <text wx:if="{{item.selected}}" class='iconfont icon-duigou icon'></text>
    </view>
  </scroll-view>
</view>

组件内的js:

/**
     * 地区选择组件
     * ===== 使用场景 ======
     * 所有选择地区的地方
     * ===== 参数 =====
     * show         地区组件是否显示
     * ===== 事件 =====
     * areasChanged 选择地区时触发,把选择的新地区传给父组件
     * closeRegionpicke  监听地区是否选择完毕,选择完毕后关闭地区组件
                * 触发areasChanged事件,即在外部,在组件上绑定areasChanged事件即可,                 即bind:areasChanged,像绑定tap一样
 */
import * as API_Address from '../../api/address'
Component({
         //接收父组件传递过来的参数
         properties:{
    show: {
      type: Boolean,
      value: false
    }
  },
  data:{
    id: 0,
    areas: [],//当前级别显示的地区
    selectedAreas: [],//存储当前选中项所属的地区列表
    choosedAreas: [],//选中的地区
    finished: false,//是否选择完毕
  },
  observers:{
//监听地区组件是否显示
show(val) {
if(val) {
this.getAreasItems()
}
},
    //监听地区是否选择完毕,选择完毕后通知父组件关闭地区组件
    finished() {
      if (this.data.finished) {
        this.triggerEvent('closeRegionpicke')
      }
    },
    //把选择的新地区传给父组件
    choosedAreas(newVal) {
      this.triggerEvent('areasChanged', newVal)
    }
  },
  methods:{
    // 已选择的地区变化时触发
    onchangeChoosedItem(e) {
      let item = e.currentTarget.dataset.item
      if (item.region_grade) {
        this.setData({
          areas: this.data.selectedAreas[item.region_grade - 1]
        })
      }
    },
    // 选择列表地区项变化时
    onchangeItem(e) {
      let item = e.currentTarget.dataset.item
      if (this.data.choosedAreas[item.region_grade - 1] && this.data.areas[0].region_grade === item.region_grade && item.id === this.data.choosedAreas[item.region_grade - 1].id) {
        return
      } else {
        this.data.choosedAreas.length = item.region_grade - 1
        if (this.data.choosedAreas[item.region_grade - 1]) {
          this.data.choosedAreas[item.region_grade - 1] = item
        } else {
          this.data.choosedAreas.push(item)
        }
//设置选择后的地区为选中状态
        this.data.areas.forEach(key => {
          if (item.id === key.id) {
            key.selected = true
          }else{
            key.selected = false
          }
        })
        item.selected = true
        this.setData({
          finished: item.region_grade === 4,
          id: item.id,
          areas:this.data.areas,
          choosedAreas: this.data.choosedAreas,
        })

        if (item.region_grade === 4) {
          return
        }
        this.getAreasItems()
      }
    },
    //获取地区列表
    getAreasItems() {
      let that = this
              //调用后台接口获取地区列表
      API_Address.getAreas(this.data.id).then(response => {
        if (response && Array.isArray(response) && response.length) {
          response.forEach(key => {
            key.selected = false
          })
          that.setData({areas: response})
          if (that.data.selectedAreas[response[0].region_grade - 1]) {
            if (response[0].region_grade === that.data.selectedAreas[response[0].region_grade - 1][0].region_grade) {
              that.data.selectedAreas[response[0].region_grade - 1] = response
            }
          } else {
            that.data.selectedAreas.push(response)
            that.setData({selectedAreas:this.data.selectedAreas})
          }
        } else {
          that.setData({finished: true})
        }
      })
    }
  }
})

三、组件调用

在需要的文件中引入组件

json文件

说明:"组件名称(随便定义)":"组件页面的路径

{
"usingComponents": {
"RegionPicker": "/components/regionpicke/regionpicke"
}
}

wxml文件

<RegionPicker
bind:areaschanged="addressSelectorChanged"
bind:cloneRegionPicke="cloneRegionPicke"
show="{{ showAddressSelector }}"
></RegionPicker>

js文件

//地址发生改变
  addressSelectorChanged(e){
    const item = e.detail //接收组件传递过来的参数
    const obj = {
      last_id: item[item.length - 1].id,
      addrs: item.map(key => { return key.local_name }).join(' ')
    }
    this.setData({
      'addressForm.region': obj.last_id,
      'addressForm.addrs': obj.addrs
    })
  },
      //关闭地区组件
                  cloneRegionPicke() {
this.setData({
showAddressSelector: false
})
    }

易族智汇(javashop)原创文章

04-06 09:35