微信小程序开发微信小程序开发

自定义组件之 Swiper 特效组件

2019-08-27  本文已影响0人  夏海峰
效果演示
一、需求说明

使用微信小程序原生代码,实现如上图的交互效果。具体要求如下:

二、封装自定义组件 <my-swiper>

根据以上需求,使用原生小程序组件和代码,封装一个 <my-swiper> 组件,完整代码如下所示。其中的要点(坑)罗列如下:

# myswiper.wxml

<view class='myswiper' style="height: {{h1}}px;" bindtap='tabTouch' bindtouchstart='touchStart' bindtouchend='touchEnd'>
  <!-- Tabs -->
  <view class="tabs">
    <view class="tab {{curIdx == index ? 'on' : ''}}" wx:for="{{tabArr}}" wx:key="{{index}}" wx:for-item="item" data-index="{{index}}" bindtap="tabClick" >
      <text class="tab-title">{{item}}</text>
      <text class="tab-line"></text>
    </view>
  </view>
  <!-- swiper -->
  <swiper class='swiper' current="{{curIdx}}" bindchange="swiperChange" style="height: {{h2}}px;">
    <swiper-item wx:for="{{tabArr}}" wx:key="{{index}}">
      <slot name='item{{index}}'></slot>
    </swiper-item>
  </swiper>
</view>

# myswiper.wxss

.myswiper {
  position: relative;
  /* height: 1200rpx; */
  background: white;
}
.tabs{
  width: 100%;
  height: 100rpx;
  background-color: #eeeeee;
  display: flex;
}
.tab{
  flex: 1;
  font-size:28rpx;
  font-family:PingFangSC;
  font-weight:400;
  color:rgba(102,102,102,1);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  font-weight: bold;
}
.tab>text{
  display: block;
}
.on .tab-line{
  width:90rpx;
  height:4rpx;
  background:rgba(255,117,56,1);
  border-radius:3rpx;
  margin-top: 5rpx;
}
.on .tab-title{
  font-size:32rpx;
  font-family:PingFangSC;
  font-weight:500;
  color:rgba(255,117,56,1);
}
.swiper swiper-item {
  /* 开启swiper-item滚动,touch流畅滚动 */
  overflow: scroll;
  -webkit-overflow-scrolling:touch;
}
# myswiper.js

let startY = 0;
Component({
  options: {
    multipleSlots: true // 启用多slot支持
  },
  properties: {
    tabArr: {   /* Tab项的名称列表 */
      type: Array,
      value: []
    }
  },
  data: {
    h1: '',   // my-swiper 组件的高度
    h2: '',   // swiper 组件的高度
    curIdx: 0 // tab 索引号
  },

  attached: function() {
    const that = this
    // 获取信息,动态设置组件高度
    wx.getSystemInfo({
      success: function(e) {
        const w = e.windowWidth
        const h = e.windowHeight
        // 100 是Tab的默认高度,单位rpx
        // 把 rpx 转化为 px
        const tabH = 100 * w / h
        that.setData({ h1: h, h2: h - tabH })
      }
    });
  },
  methods: {
    /* my-swiper 组件的系列事件 */
    tabTouch: function(e) {
      // 当用户点击my-swiper组件时,将其置顶
      const top = e.currentTarget.offsetTop
      // 滚动到顶部
      wx.pageScrollTo({scrollTop: top});
    },
    touchStart: function(e) {
      startY = e.changedTouches[0].clientY
      console.log('start', startY)
    },
    touchEnd: function(e) {
      const endY = e.changedTouches[0].clientY
      // 当手势向上滑动时,把my-swiper组件置顶
      if (startY - endY > 10) {
        const top = e.currentTarget.offsetTop
        wx.pageScrollTo({scrollTop: top});
      }
      console.log('end', endY)
    },
    // 点击标签事件
    tabClick:function(e){
      let data = e.currentTarget.dataset;
      this.setData({ curIdx: data.index })
    },
    // swiper切换事件
    swiperChange:function(e){
      this.setData({ curIdx:e.detail.current })
    },
  }
})
# myswiper.json

{ "component": true }
三、使用 <my-swiper> 组件,进行测试

<my-swiper>组件封装好了,测试代码如下。我们只需要传递一个 tabArr 标签列表进去即可。再使用 slot 插槽动态地插入多个区块的内容。

# demo.json

{
  "navigationBarTitleText": "自定义Swiper组件及特效",
  "usingComponents": {
    "my-swiper": "/component/myswiper/myswiper"
  }
}
# demo.wxml

<view>
  <view class='other'>
    <image mode='aspectFit' src='./a.png' />
  </view>

  <my-swiper tabArr="{{['人物','自然','汽车','美女']}}">
    <view slot='item0' class='content'>人物</view>
    <view slot='item1' class='content'>自然</view>
    <view slot='item2' class='content'>汽车</view>
    <view slot='item3' class='content'>美女</view>
  </my-swiper>
</view>
# demo.wxss

.other image {
    display: block;
    width: 100%;
}
.content {
    font-size: 80rpx;
    text-align: center;
    line-height: 200rpx;
}
# demo.js

Page({
  data: {},
  onLoad: function() {},
})
四、总结

<my-swiper>组件的封装,填平了一些坑,比如 swiper默认的样式问题。通过这个组件,我们至少学到了如下前端知识:

以上完整代码,复制黏贴即可实现这个效果,相关要点已经在代码中进行了注释。事实上,要总结的内容还有很多,时间有限就不啰嗦了。好了,本篇就总结到这里。

往期 相关的小程序demo笔记:


本篇结束 2019-08-27

上一篇 下一篇

猜你喜欢

热点阅读