组件封装及通信

业务开发时碰到以下场景:用户点击省份选择时,需要先向服务器请求列表数据,再显示省份列表;如请求数据失败,提示错误信息,不显示省份列表。如下图显示: -w279

但看界面非常容易,使用微信小程序picker控件就行,但是和业务结合以后发现并不可行,picker控件点击后直接显示列表,无法插入数据请求等相关逻辑。这里决定自行封装列表,然后在微信小程序JS文件写入相关业务逻辑,控制显示、消失、选中等相关逻辑。

组件封装

组件官方介绍,这里不一一介绍了,需要了解的自行阅读,主要介绍我封装的region-picker

WXML文件

<view wx:if='{{flag}}'>
  <view class='wrap {{wrapAnimate}}' style='background:rgba(0,0,0,{{bgOpacity}});'></view>
  <view catchtap='hideFrame' class='frame-wrapper {{frameAnimate}}'>
    <view catchtap='catchNone' class='frame'>
      <!-- 标题 -->
      <view class='title-wrapper'>
        <view catchtap='hideFrame' style="padding: 0 30rpx 0 30rpx;">取消</view>
        <view catchtap='_confirmEvent' class="header-confirm">确定</view>
      </view>

      <picker-view indicator-style="height: 40px;" style="width: 100%; height: 300px;" value="{{value}}" bindchange="bindChange">
        <picker-view-column>
          <view wx:for="{{array}}" wx:key="index" style="line-height: 40px; text-align: center;">{{item}}</view>
        </picker-view-column>
      </picker-view>
    </view>
  </view>
</view>

WXSS文件

/* components/region-picker/index.wxss */

.header-confirm {
  padding: 0 30rpx 0 30rpx;
  color: #B4282D;
}

.wrapAnimate{animation: wrapAnimate 0.5s ease-in-out forwards}
@keyframes wrapAnimate{
  0%{}
  100%{background:rgba(0,0,0,0.35);}
}
.wrapAnimateOut{animation: wrapAnimateOut 0.4s ease-in-out forwards}
@keyframes wrapAnimateOut{
  0%{background:rgba(0,0,0,0.35);}
  100%{background:rgba(0,0,0,0);}
}
.frameAnimate{animation: frameAnimate 0.5s ease forwards;}
@keyframes frameAnimate{
  0%{}
  100%{opacity: 1;top:0vh;}
}
.frameAnimateOut{animation: frameAnimateOut 0.4s ease forwards;}
@keyframes frameAnimateOut{
  0%{opacity: 1;top:0vh;}
  100%{opacity: 0;top:100vh;}
}
.frame-wrapper{
  position: fixed;
  height:100vh;
  width:100vw;
  z-index: 2;
  top: 50vh;
}

.frame{
  background: #fff;
  position: absolute;
  bottom: 0;
  width: 100%;
  /* padding: 5.9vw 5.9vw 0; */
  border-top-left-radius: 20rpx;
  border-top-right-radius: 20rpx;
  z-index: 3;
}

.title-wrapper{
  height: 96rpx;
  justify-content: space-between;
  color: #4a4a4a;
  border-bottom: 1rpx solid #F3F3F3;
  align-items: center;
  display: flex;
  flex-direction: row;
}

.flex{
  display: flex;
  align-items: center;
}

.wrap{
  position: fixed;
  z-index: 1;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}

JS文件


Component({
  properties: {

  },

  data: {
    flag: false,
    wrapAnimate: 'wrapAnimate',
    bgOpacity: 0,
    frameAnimate: 'frameAnimate',
    value: [0],
    array: [],
    index: -1,
  },

  properties: {
    frameTitle: {
      type: String,
      value: '标题',
    }
  },

  methods: {
    show(array, index) {
      if (index == null || index < 0 ) {
        index = 0;
      }

      this.data.index = index;
      this.showFrame();
      this.setData({
        array:array,
        value: [index]
      });
    },

    showFrame() {
      this.setData({ flag: true, wrapAnimate: 'wrapAnimate', frameAnimate: 'frameAnimate' });
    },

    hideFrame() {
      const that = this;
      that.setData({ wrapAnimate: 'wrapAnimateOut', frameAnimate: 'frameAnimateOut' });
      setTimeout(() => {
        that.setData({ flag: false })
      }, 400)
    },

    catchNone() {
      //阻止冒泡
    },

    _confirmEvent() {
      this.hideFrame();
      // 点击事件带参传入父级
      this.triggerEvent('confirmSelect', this.data.index)
    },

    bindChange: function (e) {
      console.log('picker发送选择改变,携带值为', e.detail.value)
      this.data.index = e.detail.value;
    },
  }
})

JSON文件

{
  "component": true,
  "usingComponents": {

  }
}

该组件对外提供了两个方法:

1、显示组件(show(array, index)),用于传入列表数据和索引。

2、确认列表选中索引(confirmSelect),用于数据回调。

传入数据有两种方式:第一种使用properties,在组件创建时传入,第二种是获取组件(selectComponent),再调用传入方法。

组件使用

在需要使用的界面WXML创建组件

<region-picker id="region-picker-city" bind:confirmSelect="confirmSelectCity">
</region-picker>

在需要使用的界面JS处理业务逻辑

  // 选择城市函数
  changeCity: function (e) {
    var res = ["南京市", "苏州省", "无锡省", "常州省"]
    this.selectComponent('#region-picker-city').show(res, 1);
  },

  //确认城市选择
  confirmSelectCity: function (e) {
    this.setData({
      cityIndex: e.detail,
    });
  },

至此该控件的封装及使用已经写好了,以上控件使用是简化版的,实际业务是在数据请求成功以后再调用changeCity方法,并且方法内的res是实际数据,想查看具体代码的请移至我的github工程FireShop_wx地址

总结

1、封装组件便于我们自行控制代码逻辑,便于业务扩展,同时减少重复代码。

2、学习组件封装方法,具体阅读官方文档。

3、了解组件调用和数据回调方式。

results matching ""

    No results matching ""