微信小程序封装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
相关推荐
海纳百川·纳海川1 天前
数字化升级,让废品回收更简单高效
大数据·微信小程序·小程序
VX_bysjlw9851 天前
基于微信小程序的宠物用品商城系统-后端74346-计算机毕设原创(免费领源码+带部署教程)
java·redis·微信小程序·eclipse·mybatis·idea·微信开发者工具
一只昀1 天前
基于微信小程序的咖啡店点餐小程序
微信小程序·小程序
admin and root3 天前
「移动安全」安卓APP 反编译&frida脱壳技巧分享
android·开发语言·python·web安全·微信小程序·移动安全·攻防演练
m0_462803884 天前
【无标题】
微信小程序
码农学院6 天前
微信小程序云开发实战:扫码点餐系统的高并发订单处理与外卖接单架构
微信小程序·架构·notepad++
这是个栗子6 天前
uni-app 微信小程序开发:常用函数总结(一)
微信小程序·小程序·uni-app·getcurrentpages
爱勇宝7 天前
上线 20 多天后,我才发现小程序的图片上传一直不可用
微信小程序·智能小程序
万亿少女的梦1688 天前
基于微信小程序、Spring Boot与Vue3的智慧养老管理系统设计与实现
spring boot·redis·微信小程序·mybatis·vue3
alxraves10 天前
零代码AI助手:用大模型自动生成微信小程序界面与逻辑
人工智能·微信小程序·notepad++