微信小程序封装modal对话框组件

使用方法及示例图

基础使用

bash 复制代码
<pk-model title="标题" content="内容" visible="{{ visible }}" bind:ok="handleOk" bind:cancel="handleCancel"></pk-model>

不显示取消按钮 + 自定义按钮文字

ini 复制代码
<pk-model title="标题" 
    content="内容" 
    visible="{{ visible }}" 
    bind:ok="handleOk" 
    bind:cancel="handleCancel" 
    okText="完成了" 
    showCancel="{{ false }}"></pk-model>

自定义底部按钮组

ini 复制代码
let actions = [{name: '按钮1'}, {name: '按钮2', color: '#ff9900'}, {name: '按钮3', color: '#19be6b'}]
<pk-model title="标题"
    content="内容" 
    visible="{{ visible }}" 
    bind:ok="handleOk" 
    bind:cancel="handleCancel" 
    actions="{{ actions }}"></pk-model>

自定义model(title-标题、main-内容、footer-底部按钮) // body包含title、nain 可直接自定义body

xml 复制代码
<pk-model visible="{{ visible }}">
  <view slot="title">这个是标题</view>
  <view slot="main">
    <view>一些文本</view>
    <view>一些文本</view>
    <view>一些文本</view>
    <view>一些文本</view>
  </view>
  <view slot="footer">这个是底部按钮</view>
</pk-model>
// 这里自定义的时候 样式可以通过自定义的类名等方式进行布局

wxml

xml 复制代码
<!-- mask 蒙版 -->
<view class="pk-modal-mask pk-class-mask {{ visible ? 'pk-modal-mask-show' : '' }}"></view>
<!-- mask 蒙版 -->
<view class="pk-class pk-model {{ visible ? 'pk-model-show' : '' }}">
  <view class="pk-model-container">
    <!-- body S -->
    <view class="pk-model-body-slot"><slot name="body"></slot></view>
    <view class="pk-model-body">
      <view class="pk-model-content">
        <!-- title S -->
        <view class="pk-model-title-slot">
          <slot name="title"></slot>
        </view>
        <view class="pk-model-title" wx:if="{{ title }}">{{ title }}</view>
        <!-- title E -->
        <!-- main S -->
        <view class="pk-model-main-slot"><slot name="main"></slot></view>
        <view class="pk-model-main" wx:if="{{ content }}">{{ content }}</view>
        <!-- main E -->
      </view>
    </view>
    <!-- body E -->
    <!-- footer S -->
    <view class="pk-model-footer-body">
      <view class="pk-model-footer-slot"><slot name="footer"></slot></view>
      <view class="pk-model-footer">
        <view class="pk-model-footer-custom" wx:if="{{ actions.length }}">
          <view class="{{ actionMode === 'horizontal' ? 'pk-model-footer-horizontal' : 'pk-model-footer-vertical' }}">
            <view wx:for="{{ actions }}"  wx:key="index" class="pk-model-footer-item" style="{{ item.color ? 'color:' + item.color : '' }}" data-item="{{ item }}" data-idx="{{ index }}" bindtap="handleClickItem">
              {{ item.name }}
            </view>
          </view>
        </view>
        <view class="pk-model-footer-btn" wx:else>
          <view class="pk-model-footer-item" wx:if="{{ showCancel }}" bindtap="handleClickCancel">{{ cancelText }}</view>
          <view class="pk-model-footer-item" wx:if="{{showOk}}" bindtap="handleClickOk">{{ okText }}</view>
        </view>
      </view>
    </view>
    <!-- footer E -->
  </view>
</view>

js

php 复制代码
Component({
  // externalClasses 通过 externalClasses 既可以导出当前组件需要外部设置的 class 属性
  externalClasses: ['pk-class', 'pk-class-mask'],
  options: {
    multipleSlots: true, // 在组件定义时的选项中启用多slot支持
  },
  properties: {
    // 是否显示组件
    visible: {
      type: Boolean,
      value: false
    },
    // 标题
    title: {
      type: String,
      value: ''
    },
    // 内容
    content: {
      type: String,
      value: ''
    },
    // 是否显示确定按钮
    showOk: {
      type: Boolean,
      value: true 
    },
    // 是否显示取消按钮
    showCancel: {
      type: Boolean,
      value: true 
    },
    // 确定按钮的文案
    okText: {
      type: String,
      value: '确认'
    },
    // 取消按钮的文案
    cancelText: {
      type: String,
      value: '取消'
    },
    // 按钮组
    actions: {
      type: Array,
      value: [] 
      // 按钮组参数
      // value: [{name: '按钮1'}, {name: '按钮2', color: '#ff9900'}, {name: '按钮3', color: '#19be6b'}]
    },
    // 按钮的排列方向
    actionMode: {
      type: String,
      value: 'horizontal', // horizontal || vertical
    }
  },
  methods: {
    handleClickItem({ currentTarget = {} }) {
      const dataset = currentTarget.dataset || {}
      console.log('dataset', dataset)
      this.triggerEvent('click', dataset)
    },
    handleClickOk() {
      this.triggerEvent('ok')
    },
    handleClickCancel() {
      this.triggerEvent('cancel')
    }
  }
})

wxss

css 复制代码
.pk-modal-mask {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  background: rgba(0, 0, 0, .7);
  z-index: 1000;
  transition: all .3s ease-in-out;
  opacity: 0;
  visibility: hidden;
}
.pk-modal-mask-show {
  opacity: 1;
  visibility: visible;
} 
.pk-model {
  position: fixed;
  overflow: auto;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  height: 100%;
  z-index: 1000;
  display: flex;
  outline: none;
  flex-direction: column;
  -webkit-box-align: center;
  align-items: center;
  -webkit-box-pack: center;
  justify-content: center;
  transform: translateZ(1px);
  opacity: 0;
  visibility: hidden;
}
.pk-model-show {
  visibility: visible;
  opacity: 1;
}
.pk-model-container {
  background-color: #fff;
  background-clip: padding-box;
  border-radius: 16rpx;
  border: 0;
  overflow: hidden;
}
.pk-model-body-slot:empty + .pk-model-body {
  display: flex;
}
.pk-model-body {
  display: none;
  width: 540rpx;
  position: relative;
}
.pk-model-content {
  padding-top: 30rpx;
  position: relative;
  background-color: #fff;
  border: 0;
  background-clip: padding-box;
  text-align: center;
  flex: 1;
  height: 100%;
  overflow: hidden;
}
.pk-model-title-slot:empty + .pk-model-title {
  display: flex;
  /* display: block; */
}
.pk-model-title {
  display: none;
  padding: 10rpx 30rpx 30rpx;
  margin: 0;
  font-size: 36rpx;
  width: 100%;
  line-height: 1;
  color: #000;
  justify-content: center;
}
.pk-model-main-slot:empty + .pk-model-main {
  display: flex;
}
.pk-model-main {
  display: none;
  max-height: 200rpx;
  margin-bottom: 30rpx;
  font-size: 28rpx;
  color: #a4a4a4;
  height: 100%;
  line-height: 1.5;
  overflow: auto;
  justify-content: center;
}
.pk-model-footer-slot:empty + .pk-model-footer {
  display: flex;
}
.pk-model-footer {
  display: none;
  border-top: 1px solid #e9eaec;
  overflow: hidden;
}
.pk-model-footer-custom {
  flex: 1;
}
.pk-model-footer-horizontal {
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.pk-model-footer-vertical {
  width: 100%;
  display: flex;
  flex-direction: column;
}
.pk-model-footer-btn {
  flex: 1;
  display: flex;
  justify-content: space-between;
}
.pk-model-footer-item {
  flex: 1;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 26rpx 10rpx;
  font-size: 24rpx;
  border-right: 1px solid #e9eaec;
  box-sizing: border-box;
}

.pk-model-footer-item:last-child {
  border-right: 0;
  border-bottom: 0;
}
.pk-model-footer-vertical .pk-model-footer-item {
  border-right: 0;
  border-bottom: 1px solid #e9eaec;
}

json

json 复制代码
{
  "component": true
}

API

参数 说明 类型 默认值
visible 是否显示组件 Boolean false
title 标题 String ''
content 内容 String ''
showOk 是否显示确定按钮 Boolean true
showCancel 是否显示取消按钮 Boolean true
okText 确定按钮的文案 String 确认
cancelText 取消按钮的文案 String 取消
actions 按钮组[{name: '按钮1', color: '#19be6b'}] Array []
actionMode 按钮的排列方向 'horizontal','vertical' String horizontal

Slots

名称 说明
body body包含titlecontent,设置了body这两个值则不生效
title 标题部分
content 内容部分
footer 底部按钮部分

Events

事件名 说明 回调参数
click 使用actions时点击按钮时触发 event:{item, idx}
ok 点击确认按钮时触发 event:event
cancel 点击取消按钮时触发 event:event
相关推荐
甜甜的资料库2 小时前
基于小程序老人监护管理系统源码数据库文档
微信小程序
Uyker18 小时前
微信小程序动态效果实战指南:从悬浮云朵到丝滑列表加载
前端·微信小程序·小程序
happyCoder1 天前
uniapp 微信小程序实现定时消息订阅提醒(前后端)
微信小程序
Uyker1 天前
从零开始制作小程序简单概述
前端·微信小程序·小程序
打小就很皮...2 天前
HBuilder 发行Android(apk包)全流程指南
前端·javascript·微信小程序
前端缘梦2 天前
微信小程序登录方案实践-从账号体系到用户信息存储
前端·微信小程序
coding随想2 天前
2025年小程序开发全解析:技术储备、行业趋势与实战案例
微信小程序
Nueuis2 天前
微信小程序前端面经
前端·微信小程序·小程序
轩1153 天前
实现仿中国婚博会微信小程序
微信小程序·小程序
知否技术3 天前
2025微信小程序开发实战教程(一)
前端·微信小程序