微信小程序封装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
相关推荐
sheji34166 小时前
【开题答辩全过程】以 基于微信小程序的少儿编程学习平台为例,包含答辩的问题和答案
学习·微信小程序·小程序
const_qiu8 小时前
微信小程序自动化测试100%通过率实践
微信小程序·小程序
一字白首12 小时前
微信小程序进阶实战:从 UI 组件库到全局状态管理全解DAY05
ui·微信小程序·小程序
海石1 天前
微信小程序开发02:原始人也能看懂的着色器与视频处理
前端·微信小程序·视频编码
li9056632801 天前
hanzi-writer-miniprogram Path2D问题以及Bug修复
微信小程序·bug
mon_star°2 天前
基于微信小程序原生框架搭建的转盘小程序1.0(附源码)
微信小程序·小程序·notepad++
Emma_Maria2 天前
【小程序】插件申请成功,待插件提供方确认通过申请后才能使用
微信小程序
捕捉一只前端小白2 天前
cpolar内网穿透以及微信小程序域名设置
前端·vue.js·微信小程序·小程序
demo007x2 天前
如何提高 AI 做小程序的效率?
微信小程序·ai编程·claude
kaolagirl2 天前
微信小程序-滑动拼图安全验证
安全·微信小程序·小程序