微信小程序弹窗方案

最近小程序要实现如下的弹窗效果

能想到两个方案

  1. 使用 WeUI 组件库 (opens new window)自带的弹窗组件 mp-dialog
  2. 不使用WeUI组件库组件,自己定义

两种方案分别试了试,发现方案二更加适合上面这种应用场景,这两种方案的样式实现不一样,但是控制展示的逻辑是一致的,都是通过一个布尔变量来控制是否展示,然后在页面中更新布尔变量来控制弹窗是否展示。

具体实践如下:

# WeUI 组件库 mp-dialog 实现

WeUI 是同微信原生视觉体验一致的 UI 组件库,由微信官方设计团队和小程序团队为微信小程序量身打造的。

想要使用 mp-dialog,我们需要先引入 WeUI 组件库,引入WeUI 组件库有两种方式:

  1. 通过 useExtendedLib (opens new window) 扩展库 的方式引入。
  2. 可以通过 npm 方式下载构建,npm 包名为 weui-miniprogram。

这里最好使用第一种引入方案,原因有两个

  1. 使用拓展库方式引入的组件将不会计入代码包大小。这对于控制小程序包大小非常有用。
  2. 使用 npm 方式引入的 WeUI 组件,最终可能会遇到展示效果的问题。

我自己通过 npm 引入后使用 mp-dialog,发现就是普通的样式,并不是弹窗。但同样的 mp-dialog 使用方式,改成拓展库方式引用就没有这个问题。

通过拓展库引入的方式也很简单,就直接在全局配置文件 app.json 里面配置。

{
  "useExtendedLib": {
    "weui": true
  }
}

然后在对应的页面中直接引用

{
  "usingComponents": {
    "mp-dialog": "weui-miniprogram/dialog/dialog",
    "mp-icon": "weui-miniprogram/icon/icon"
  }
}

在 wxml 里面引入如下

<mp-dialog ext-class="dialog-container" show="{{showDialog}}" bindclose="tapClose">
    <view class="qrcode-bg">
      <view class="qrcode-hint">
        了解我
      </view>
      <image class="qrcode" src="qrcodeurl" mode=""/>
    </view>
</mp-dialog>

但是遇到下面这种 close 按钮样式,这种 mp-dialog 方式就没有办法去进行自定义了,我上网找了一些方案,感觉比较麻烦,所以就改用第二种方式实现

# 自定义弹窗实现

基本的视图结构如下

mask(蒙层)
 | - modeal-dialog(弹窗整体区域)
      | - qrcode-bg(白色背景区域)
          | - qrcode-hint(提示)
          | - qrcode(二维码)
      | - close-icon(关闭按钮)

具体 wxml 代码如下

<view>
  <view class="modal-mask" bindtap="hideModal" catchtouchmove="preventTouchMove" wx:if="{{showDialog}}">
    <view class="modal-dialog" wx:if="{{showDialog}}">
      <view class="qrcode-bg">
        <view class="qrcode-hint">了解我</view>
        <image class="qrcode" src="https://cdnv2.ruguoapp.com/Fo7soQMtG7rg0SBLKrFQt-JMO46Nv3.png?imageMogr2/auto-orient/thumbnail/640000@%7Cwatermark/3/image/aHR0cHM6Ly93YXRlcm1hcmsucnVndW9hcHAuY29tLz90ZXh0PSVFNSU4RCVCMyVFNSU4OCVCQiUyMCU0MGZhbnRodXMmaGVpZ2h0PTQw/gravity/SouthEast/dx/10/dy/10" mode="scaleToFill" />
      </view>
      <mp-icon class="close-icon" icon="close2" color="white" size="{{40}}"> 
      </mp-icon>
    </view>
  </view>
</view>

样式代码如下

.modal-mask {
	//弹窗位于蒙层中央布局
  display: flex;     
  justify-content: center;
  align-items: center;
	//固定布局
  position: fixed;   
  //边距都设置为 0 填满窗口
  left: 0rpx;
	right: 0rpx; 
  top: 0rpx;
  bottom: 0rpx;
  //蒙层背景色
  background-color: rgba(0, 0, 0, 0.5);
  //保证蒙层能盖住当前视图
  z-index: 999;
}

.modal-dialog {
  //弹窗视图flex布局
  display: flex;
  flex-direction: column;
  justify-content: start;
  align-items: center;
  overflow: hidden;
  z-index: 9999;

  .qrcode-bg {
    display: flex;
    flex-direction: column;
    justify-content: start;
    align-items: center;
    width: 512rpx;
    height: 566rpx;
    background-color: white;
    border-radius: 36rpx;

    .qrcode-hint {
      margin-top: 58rpx;
      color: #804AF6;
      font-weight: 600;
      font-size: 32rpx;
    }

    .qrcode {
      margin-top: 28rpx;
      width: 364rpx;
      height: 364rpx;
    }
  }

  .close-icon {
    margin-top: 56rpx;
  }

}

总结就是这种自定义程度比较高的,还是自定义实现比较方便。

参考地址:

  1. WeUI组件库简介 (opens new window)
  2. 微信小程序开发之——Dialog弹窗 (opens new window)

关注我的微信公众号,我在上面会分享我的日常所思所想。