[组件封装]微信小程序-底部弹框

描述

模仿ios浏览器底部弹框效果。
遮罩层淡入淡出,弹框高度根据内容自适应。

效果

源码

<!-- popup-bottom.wxml -->
<view class="wrap" hidden="{{!myVisible}}">
  <view class="mask {{visible ? 'mask-show' : ''}}" bindtap="_onCancel"></view>
  <view class="box" id="modal-box" animation="{{animationData}}">
    <slot />
  </view>
</view>
// popup-bottom.js
Component({
  properties: {
    myVisible: {
      type: Boolean,
      value: false,
      observer: '_visibleChange',
    },
  },

  data: {
    visible: false,
    animation: null,
    animationData: null,
  },

  ready: function () {
    const animation = wx.createAnimation({
      duration: 200,
      timingFunction: "linear",
      delay: 0,
    });
    this.setData({
      animation,
    })
  },

  methods: {
    _visibleChange: function (newVal, oldVal, changedPath) {
      if (oldVal === false && newVal === true) {
        setTimeout(function () {
          this._onShow();
        }.bind(this), 0)
      }
    },

    _onShow: function () {
      const __this = this;
      const query = wx.createSelectorQuery().in(this);
      query.select('#modal-box').boundingClientRect(function (res) {
        const { animation } = __this.data;
        animation.translateY(-res.height).step();
        __this.setData({
          visible: true,
          animationData: animation.export(),
        })
      }).exec();
    },

    _onCancel: function () {
      const { animation } = this.data;
      animation.translateY(0).step();
      this.setData({
        visible: false,
        animationData: animation.export(),
      })
      setTimeout(function () {
        this.triggerEvent('myOnCancel');
      }.bind(this), 200)
    },

  },
})

/* popup-bottom.wxss */
.wrap {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 99999;
  width: 100vw;
  height: 100vh;
}

.mask {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
  background: #000;
  opacity: 0;
  transition: 0.2s;
}
.mask-show {
  opacity: 0.4;
}

.box {
  position: fixed;
  top: 100vh;
  left: 0;
  z-index: 2;
  width: 100%;
  min-height: 100rpx;
  background: #fff;
}

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

使用

test.wxml

<button bindtap="handleShow">点我弹出popup</button>
<popup-bottom myVisible="{{visible}}" bindmyOnCancel="handleCancel">
  <view>我是内容</view>
  <view>我是内容</view>
  <view>我是内容</view>
  <view>我是内容</view>
  <view>我是内容</view>
</popup-bottom>

test.js

Page({
  data: {
    visible: false,
  },

  handleShow: function () {
    this.setData({ visible: true });
  },

  handleCancel: function () {
    this.setData({ visible: false });
  },
})

test.json

{
  "navigationBarTitleText": "底部弹框",
  "usingComponents": {
    "popup-bottom": "/components/popup-bottom/popup-bottom"
  }
}

猜你喜欢

转载自www.cnblogs.com/whosMeya/p/12557510.html