微信小程序封装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
相关推荐
“负拾捌”12 小时前
python + uniapp 结合腾讯云实现实时语音识别功能(WebSocket)
python·websocket·微信小程序·uni-app·大模型·腾讯云·语音识别
换日线°1 天前
NFC标签打开微信小程序
前端·微信小程序
菜鸟una2 天前
【微信小程序+Taro 3+NutUI 3】input (nut-input) 、 textarea (nut-texteare)类型使用避坑
前端·vue.js·微信小程序·小程序·taro
计算机毕设指导62 天前
基于微信小程序的校园二手交易系统【源码文末联系】
java·spring boot·spring·微信小程序·小程序·tomcat·maven
Java.慈祥2 天前
速通-微信小程序 2Day
微信小程序·小程序·前端框架
2501_933907212 天前
宁波小程序公司是什么?主要提供宁波微信小程序制作与服务吗?
科技·微信小程序·小程序
码云数智-大飞2 天前
微信商城小程序怎么弄?2026年主流小程序商城平台对比
微信小程序
计算机毕设指导63 天前
基于微信小程序的非物质文化遗产推广管理系统【源码文末联系】
java·spring boot·mysql·微信小程序·小程序·tomcat·maven
软件聚导航3 天前
马年、我用AI写了个“打工了马” 小程序
人工智能·ui·微信小程序
大黄说说3 天前
微信商城小程序怎么弄?微信购物小程序怎么开通
微信小程序