美文网首页
微信小程序自定义sheet-action,实现底部弹出动画

微信小程序自定义sheet-action,实现底部弹出动画

作者: smallzip | 来源:发表于2020-04-04 15:46 被阅读0次

    效果

    小程序自定义sheet-action.gif

    小程序自定义底部弹出modal框组件,仿照小程序sheet-action的效果,封装成组件直接在其他业务页面公用。

    1. 底部弹出动画使用的是小程序的animation,弹出动画可以根据自行需求去替换。
    2. modal顶部有一条短的横线,向下滑动可以触发隐藏modal
    3. 点击阴影部分可以触发隐藏modal

    使用方法

    1. 在业务页面引入组件
    // pages/index/index.json
    {
      "usingComponents": {
        "product-cart": "../../components/product-cart/index"
      }
    }
    
    // pages/index/index.js
    Page({
      data: {
        show: false // true:显示  false:隐藏
      },
    showModal(){
      this.setData({
           show:true
        })
      },
    )}
    
    1. show参数是boolean值
    // pages/index/wswl
    <view>
      <button bindtap="showModal">点击</button>
     <product-cart show="{{show}}"></product-cart>
    </view>
    

    组件源码

    // pages/index/components/buy/index.js
    let pageY = 0;
    Component({
      options: {
        styleIsolation: 'isolated'
      },
      /**
       * 组件的属性列表
       */
      properties: {
        show: {
          type: Boolean,
          value: false
        }
      },
      /**
       * 组件的初始数据
       */
      data: {
        list: [{
            name: '快递',
            selected: 1,
          },
          {
            name: '自提',
            selected: 0
          }
        ],
        animate: {},
        hideModal: false, //模态框的状态  false-隐藏  true-显示
      },
      /**
       * 数据监听
       */
      observers: {
        'show': function(val) {
          if (val) {
            this.showModal()
          } else {
            this.hideModal()
          }
        }
      },
      /**
       * 组件的方法列表
       */
      methods: {
        // 显示遮罩层
        showModal() {
          this.setData({
            hideModal: true
          })
          const animation = wx.createAnimation({
            duration: 500,
            timingFunction: 'ease',
          })
          // 先显示背景再执行动画,translateY(0)偏移量为0代表显示默认高度
          setTimeout(() => {
            animation.translateY(0).step()
            this.setData({
              animate: animation.export()
            })
          }, 50)
        },
        // 隐藏遮罩层
        hideModal() {
          const animation = wx.createAnimation({
            duration: 500,
            timingFunction: 'ease',
          })
          // 设置为100vh可以确保滚动到底部,可以按照自己的内容高度设置,能够滑到底部即可
          animation.translateY('100vh').step()
          this.setData({
            animate: animation.export(),
          })
          // 先执行动画,再隐藏组件
          setTimeout(() => {
            this.setData({
              hideModal: false
            })
          }, 300)
        },
        // 移动
        touchMove(e) {
          const clientY = e.changedTouches[0].clientY
          if (clientY - pageY > 0 && clientY - pageY > 50) {
            this.hideModal()
          }
        },
        // 触摸开始
        touchStart(e) {
          pageY = e.changedTouches[0].clientY;
        },
        // 选择类型
        changeItem(e) {
          const {
            index
          } = e.currentTarget.dataset
          this.data.list.forEach((e, i) => {
            if (i == index) {
              e.selected = 1
            } else {
              e.selected = 0
            }
          })
          this.setData({
            list: this.data.list
          })
        },
        // 确认
        confirm() {
          this.hideModal()
        },
      }
    })
    
    <!--pages/index/components/buy/index.wxml-->
    <view class="box" hidden="{{!hideModal}}">
      <view class="empty-box" bindtap="hideModal" id="empty-box"></view>
      <scroll-view scroll-y style="max-height:80vh;">
        <view class="content" style="transform:translateY({{translateY}}px);" animation="{{animate}}">
          <!-- boll -->
          <view class="header" bindtouchstart="touchStart" bindtouchmove="touchMove">
            <view></view>
          </view>
    
          <!-- 快递类型 -->
          <view>
            <view class="item" wx:for="{{list}}" wx:key="index" bindtap="changeItem" data-index="{{index}}">
              <view class="item-name">{{item.name}}</view>
              <view>
                <view class="item-no-selected" wx:if="{{item.selected==0}}"></view>
                <image class="item-selected" wx:if="{{item.selected==1}}" src="/assets/images/choose.png"></image>
              </view>
            </view>
          </view>
    
          <!-- 按钮 -->
          <view class="button" bindtap="confirm">
            <view>确认</view>
          </view>
    
        </view>
      </scroll-view>
    </view>
    
    /* pages/index/components/buy/index.wxss */
    
    .flex {
      display: flex;
      align-items: center;
    }
    
    .box {
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      z-index: 1000;
      width: 100vw;
      height: 100vh;
      background: rgba(0, 0, 0, 0.5);
      display: flex;
      flex-direction: column;
    }
    
    .empty-box {
      flex: 1;
      background-color: transparent;
    }
    
    /* 内容视图 */
    
    .content {
      width: 100vw;
      background: rgba(255, 255, 255, 1);
      opacity: 1;
      border-radius: 20px 20px 0px 0px;
      z-index: 1001;
    }
    
    /* 头部 */
    
    .header {
      position: relative;
      height: 80rpx;
      width: 100vw;
    }
    
    .header > view {
      position: absolute;
      top: 26rpx;
      left: calc(50vw - 30rpx);
      width: 60rpx;
      height: 10rpx;
      background: rgba(161, 166, 175, 1);
      opacity: 0.6;
      border-radius: 6rpx;
    }
    
    /* 快递 */
    
    .item {
      display: flex;
      align-items: center;
      justify-content: space-between;
      width: calc(100vw - 80rpx);
      padding: 0 40rpx;
      height: 100rpx;
      background: rgba(255, 255, 255, 1);
      opacity: 1;
    }
    
    .item-no-selected {
      width: 36rpx;
      height: 36rpx;
      background: rgba(255, 255, 255, 1);
      border: 2rpx solid rgba(112, 112, 112, 1);
      border-radius: 50%;
      opacity: 0.5;
    }
    
    .item-selected {
      width: 40rpx;
      height: 40rpx;
    }
    
    /* 按钮 */
    
    .button {
      width: 100vw;
      padding: 80rpx 40rpx 20rpx 40rpx;
    }
    
    .button >view {
      width: calc(100% - 80rpx);
      height: 98rpx;
      border-radius: 50rpx;
      line-height: 98rpx;
      text-align: center;
      font-size: 32rpx;
      font-family: PingFang SC;
      font-weight: bold;
      color: rgba(255, 255, 255, 1);
      background: rgba(237, 58, 74, 1);
      opacity: 1;
    }
    
    

    相关文章

      网友评论

          本文标题:微信小程序自定义sheet-action,实现底部弹出动画

          本文链接:https://www.haomeiwen.com/subject/sqjjphtx.html