uniapp之自定义弹窗(允许插入可编辑表单)

mac2022-10-02  22

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"

本文可以作为一个模板,中间内容及标题部分有变化,可以直接在此基础上修改。

最新回复(0)