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


    一、需求背景

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

     

     

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

     

    二、代码封装

    首先在components文件下新建一个regionpicke文件夹, 再在该文件夹下新建Component(一个自定义组件由json,wxml,wxss,js四个文件组成)

    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)原创文章 

  • 相关阅读:
    Maven仓库是什么
    Maven的工程类型有哪些?
    什么是Maven?
    MyBatis 与 Hibernate 有哪些不同?
    MySQL里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据?
    使用过Redis做异步队列么,你是怎么用的?
    我们怎样才能在动作类中获得Servlet API请求,响应,HttpSession等对象?
    forward 和redirect的区别 ?
    你所知道的微服务技术栈有哪些?请列举一二
    SpringMVC流程?
  • 原文地址:https://www.cnblogs.com/javashop-docs/p/13385123.html
Copyright © 2020-2023  润新知