uniapp之自定义弹窗(允许插入可编辑表单)
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"
本文可以作为一个模板,中间内容及标题部分有变化,可以直接在此基础上修改。