uniapp自带的模态框,不支持content部分插入可编辑的表单元素,这一点比较局限。首先看一下实现的效果图,再进一步附上源码加讲解。
1、编写公共的模态框组件,在components文件下创建一个文件叫uni-dialog.vue的文件
<!-- 模态框公共部分界面 --> <template> <view v-if="showPopup" class="uni-popup"> <!-- 遮罩层结构 --> <view :class="[ani, animation ? 'ani' : '', !custom ? 'uni-custom' : '']" class="uni-popup__mask" @click="close(true)" /> <!-- 弹窗主题利用插槽 --> <view :class="[type, ani, animation ? 'ani' : '', !custom ? 'uni-custom' : '']" class="uni-popup__wrapper" @click="close(true)" > <view class="uni-popup__wrapper-box" @click.stop="clear"> <slot /> </view> </view> </view> </template> <script> export default { name: 'UniPopup', props: { // 开启动画 animation: { type: Boolean, default: true }, // 弹出层类型,可选值,top: 顶部弹出层;bottom:底部弹出层;center:全屏弹出层 type: { type: String, default: 'center' }, // 是否开启自定义 custom: { type: Boolean, default: false }, // maskClick maskClick: { type: Boolean, default: true }, show: { type: Boolean, default: true } }, data() { return { ani: '', // 动画样式类名 showPopup: false } }, watch: { show(newValue) { if (newValue) { this.open() } else { this.close() } } }, created() {}, methods: { clear() {}, open() { this.$emit('change', { show: true }) this.showPopup = true this.$nextTick(() => { setTimeout(() => { this.ani = 'uni-' + this.type }, 30) }) }, close(type) { if (!this.maskClick && type) return this.$emit('change', { show: false }) this.ani = '' this.$nextTick(() => { setTimeout(() => { this.showPopup = false }, 300) }) } } } </script> <style> @charset "UTF-8";
.uni-popup { position: fixed; top: 0; top: 0; bottom: 0; left: 0; right: 0; z-index: 998; overflow: hidden }
.uni-popup__mask { position: absolute; top: 0; bottom: 0; left: 0; right: 0; z-index: 998; background: rgba(0, 0, 0, .4); opacity: 0 }
.uni-popup__mask.ani { transition: all .3s }
.uni-popup__mask.uni-bottom, .uni-popup__mask.uni-center, .uni-popup__mask.uni-top { opacity: 1 }
.uni-popup__wrapper { position: absolute; z-index: 999; box-sizing: border-box }
.uni-popup__wrapper.ani { transition: all .3s }
.uni-popup__wrapper.top { top: 0; left: 0; width: 100%; transform: translateY(-100%) }
.uni-popup__wrapper.bottom { bottom: 0; left: 0; width: 100%; transform: translateY(100%) }
.uni-popup__wrapper.center { width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; transform: scale(1.2); opacity: 0 }
.uni-popup__wrapper-box { position: relative; box-sizing: border-box }
.uni-popup__wrapper.uni-custom .uni-popup__wrapper-box { padding: 30upx; background: #fff }
.uni-popup__wrapper.uni-custom.center .uni-popup__wrapper-box { position: relative; max-width: 80%; max-height: 80%; overflow-y: scroll }
.uni-popup__wrapper.uni-custom.bottom .uni-popup__wrapper-box, .uni-popup__wrapper.uni-custom.top .uni-popup__wrapper-box { width: 100%; max-height: 500px; overflow-y: scroll }
.uni-popup__wrapper.uni-bottom, .uni-popup__wrapper.uni-top { transform: translateY(0) }
.uni-popup__wrapper.uni-center { transform: scale(1); opacity: 1 } </style>
2、去相应界面引用这个组件,类似elementUI中的el-dialog标签一样,类似的用法。点击回退按钮,显示弹窗。
<button type="warn" @click="returnClick">回退</button>
<!-- 回退弹窗 --> <uni-popup :show="showDailog" type="center" :custom="true" :mask-click="false" @change="change"> <view class="uni-tip"> <!-- 标题 --> <view class="uni-tip-title">回退原因:</view> <view class="uni-tip-content"> <!-- 中间内容进行自定义 --> <textarea class="uni-tip-content-textarea" focus="true" placeholder="请输入回退原因" maxlength="-1" v-model="content" /> </view> <!-- 按钮部分 --> <view class="uni-tip-group-button"> <button type="primary" @click="query">确定</button> <button type="warn" @click="cancel">取消</button> </view> </view> </uni-popup>
import uniPopup from '@/components/uni-dialog.vue' // 自定义弹窗组件
export default { components: { uniPopup }, data() { return { showDailog: false, // 是否显示弹窗 content:'' // 回退原因 } }, onLoad:function(option){ }, methods: { /** 回退方法 */ returnClick(){ this.showDailog = true }, /** 回退弹窗取消方法 */ cancel() { this.showDailog = false }, /** 回退弹窗确定方法 */ query() { this.showDailog = false }, /** 监听弹窗状态是否打开 */ change(e) { console.log(e.show) } } }
/* 提示窗口 */ .uni-tip { padding: 15px; width: 300px; background: #fff; box-sizing: border-box; border-radius: 10px; }
.uni-tip-title { text-align: center; font-weight: bold; font-size: 16px; color: #333; text-align: left; }
.uni-tip-content { padding: 15px; font-size: 14px; color: #666; /* background: #C8C7CC; */ border:2upx solid #ccc; border-radius: 10upx; } .uni-tip-content-textarea{ height: 300upx; width: 100%; text-align: left; } .uni-tip-group-button { margin-top: 10px; display: flex; } .uni-tip-group-button>button{ font-size:24upx; height: 40upx; line-height: 40upx; }
要特别注意的是,uniapp中textarea组件,默认最大输入长度140,如果需要长度不受限制,需要加入一个属性maxlength="-1"
本文可以作为一个模板,中间内容及标题部分有变化,可以直接在此基础上修改。