先上效果:



组件源码:slot-modal.vue

<template>
<view class="modal-container" v-if="show" @click.stop="cancel(2)">
<view class="modal-content">
<view class="modal-head modal-title-padding">
<slot name="modal-head"></slot>
</view>
<view class="modal-body">
<slot name="modal-body"></slot>
</view>
<view class="modal-footer">
<view class="modal-col" hover-class="modal-hover" v-if="cancelText" @click.stop="cancel('cancel')">
<text :style="cancelStyle" class="modal-row-text">{{cancelText}}</text>
</view>
<view :style="confirmStyle" class="modal-col modal-confirm" hover-class="modal-hover" @click.stop="confirm">
<text :style="confirmStyle" class="modal-row-text">{{confirmText}}</text>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'modal',
props: {
//默认是否显示
show: {
type: Boolean,
default: true
},
//取消按钮文字
cancelText: {
type: String,
default: ''
},
//取消样式
cancelStyle: {
type: [String, Object]
},
//确定按钮文字
confirmText: {
type: String,
default: '确定'
},
//确定样式
confirmStyle: {
type: [String, Object]
},
//阻止点击对话框外侧锁屏
disableScreenClick: {
type: Boolean,
default: false
}
},
methods: {
confirm() {
this.$emit('confirm')
},
cancel(type) {
if (!this.disableScreenClick || type === 'cancel') {
this.$emit('cancel')
}
}
}
}
</script>
<style lang="scss" scoped>
$fontSizeLg:17px;
$fontSizeSm:15px; .modal-container {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 999;
background-color: rgba(0, 0, 0, .6);
transition: all 5s;
display: flex;
align-items: center;
justify-content: center; .modal-content {
width: 80%;
border-radius: 26rpx;
background: #FFFFFF;
overflow: hidden;
animation: fadeZoom .15s linear; .modal-head {
padding: 30rpx 30rpx 0;
text-align: center;
color: #000;
font-size: $fontSizeLg;
font-weight: 700;
} .modal-title-padding {
padding-bottom: 30rpx;
} .modal-body {
overflow:auto;
padding: 40rpx 30rpx;
font-size: $fontSizeSm;
color: #000;
text-align: center;
} .modal-footer {
display: flex;
position: relative;
text-align: center;
font-size: $fontSizeLg;
line-height: 100rpx;
color: #007AFF;
border-top: 0.5px solid rgba(9, 20, 31, 0.13); .modal-col {
flex: 1;
width: 100%;
position: relative;
} .modal-col:first-child::after {
content: '';
position: absolute;
top: 0;
bottom: 0;
right: 0;
border-right: 1px solid rgba(9, 20, 31, 0.13);
transform: scaleX(.36);
} .modal-confirm {
color: rgb(0, 122, 255);
} .modal-hover {
background-color: #f2f2f2;
}
} .modal-footer::after {
content: '';
position: absolute;
left: 0;
right: 0;
top: 0;
border-top: 0.5px solid rgba(9, 20, 31, 0.13);
transform: scaleY(.36);
}
} @keyframes fadeZoom {
0% {
transform: scale(.7);
opacity: .6;
} 80% {
transform: scale(1.2);
opacity: .3;
} 100% {
transform: scale(1);
opacity: 1;
}
}
}
</style>

使用示例:

<template>
<view class="content">
<image class="logo" src="/static/logo.png"></image>
<view class="text-area">
<text class="title">{{title}}</text>
</view>
<view><button type="default" @click="privacyDialogShow=true">用户协议</button></view>
<slot-modal
class="modal-privacy"
:show="privacyDialogShow"
:disableScreenClick="true"
confirmText="同意"
cancelText="不同意"
@cancel="cancelPrivacy"
@confirm="confirmPrivacy">
<template slot="modal-head">
<text>用户协议及隐私政策</text>
</template>
<template slot="modal-body">
<view class="index-content">
<text>
我们非常重视隐私和个人信息保护,请您先认真阅读
<text class="privacyPolicy" @click.stop="goPage('agreement')">《用户服务协议》</text>和
<text class="privacyPolicy" @click.stop="goPage('privacy')">《隐私政策》</text>的全部条款,接受全部条款后再开始使用我们的服务。
<text v-for="item in 40">我们非常重视隐私和个人信息保护,请您先认真阅读我们非常重视隐私和个人信息保护,请您先认真阅读我们非常重视隐私和个人信息保护,请您先认真阅读</text>
</text>
</view> </template>
</slot-modal>
</view>
</template> <script>
export default {
data() {
return {
title: 'Hello',
privacyDialogShow:false
}
},
onLoad() { },
methods: {
goPage(pageUrl){
console.log(pageUrl)
uni.navigateTo({
url:'../agreement/agreement'
})
},
confirmPrivacy(){
console.log('同意了用户协议')
console.log(this.privacyDialogShow)
this.privacyDialogShow = false
console.log(this.privacyDialogShow)
},
cancelPrivacy(){
console.log('拒绝了用户协议')
this.privacyDialogShow=false
}
}
}
</script> <style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
} .logo {
height: 200rpx;
width: 200rpx;
margin-top: 200rpx;
margin-left: auto;
margin-right: auto;
margin-bottom: 50rpx;
} .text-area {
display: flex;
justify-content: center;
} .title {
font-size: 36rpx;
color: #8f8f94;
}
.index-content{
max-height: 800rpx;
}
</style>

通过这次学习,遗留了一个问题还未解决:如何限制modal-body的高度为80%,尝试了多种方法无效,只能写固定高度了。

练习了

  • (1). 组件自定义事件
  • (2). 对话框的css布局

uniapp 自定义弹窗组件的更多相关文章

  1. 基于JQ的自定义弹窗组件

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. 微信小程序 - 自定义弹窗组件

    2019-01-06:简化了一些代码,以及增加了可用性. // 弹窗配置 dialogConfig: { // 弹窗 dialogvisible: false, options: { // 显示关闭按 ...

  3. uni-app自定义Modal弹窗组件|仿ios、微信弹窗效果

    介绍 uniapp自定义弹窗组件uniPop,基于uni-app开发的自定义模态弹窗|msg信息框|alert对话框|confirm确认框|toast弱提示框 支持多种动画效果.多弹窗类型ios/an ...

  4. 百度智能小程序弹窗组件wcPop|智能小程序自定义model弹窗模板

    百度智能小程序自定义弹窗组件wcPop|百度小程序model对话框|智能小程序弹窗界面模板 最近百度也推出了自己的智能小程序,如是就赶紧去试了下,官方提供的api还不是狠完整.而且官方提供的弹窗组件也 ...

  5. 基于React.js网页版弹窗|react pc端自定义对话框组件RLayer

    基于React.js实现PC桌面端自定义弹窗组件RLayer. 前几天有分享一个Vue网页版弹框组件,今天分享一个最新开发的React PC桌面端自定义对话框组件. RLayer 一款基于react. ...

  6. vue3系列:vue3.0自定义全局弹层V3Layer|vue3.x pc桌面端弹窗组件

    基于Vue3.0开发PC桌面端自定义对话框组件V3Layer. 前两天有分享一个vue3.0移动端弹出层组件,今天分享的是最新开发的vue3.0版pc端弹窗组件. V3Layer 一款使用vue3.0 ...

  7. svelte组件:Svelte自定义弹窗Popup组件|svelte移动端弹框组件

    基于Svelte3.x自定义多功能svPopup弹出框组件(组件式+函数式) 前几天有分享一个svelte自定义tabbar+navbar组件,今天继续带来svelte自定义弹窗组件. svPopup ...

  8. 支付宝小程序自定义弹窗插件|支付宝dialog插件|model插件

    支付宝小程序自定义弹窗组件wcPop|小程序自定义对话框|actionSheet弹窗模板 支付宝小程序官方提供的alert提示框.dialog对话框.model弹窗功能比较有限,有些都不能随意自定义修 ...

  9. js实现自定义弹窗

    众所周知,浏览器自带的原生弹窗很不美观,而且功能比较单一,绝大部分时候我们都会按照设计图自定义弹窗或者直接使用注入layer的弹窗等等.前段时间在慕课网上看到了一个自定义弹窗的实现,自己顺便就学习尝试 ...

随机推荐

  1. Spring听课笔记(tg)AOP

    好文:https://blog.csdn.net/javazejian/article/details/56267036 通过一个实例来理解 1.  需求:实现算术计算器,可以加减乘除,同时记录日志 ...

  2. SpringBoot配置文件 application.properties,yaml配置

    SpringBoot配置文件 application.properties,yaml配置 1.Spring Boot 的配置文件 application.properties 1.1 位置问题 1.2 ...

  3. 记一次,Docker镜像1G多精简至300+M的过程

    记一次,Docker镜像1G多精简至300+M的过程 一.业务场景描述 二.Docker时区不一致,相差8小时 三.通过Docker发布的服务上传文件上传不上去 四.上传的图片带水印,水印中包含的字体 ...

  4. SparkStreaming直连方式读取kafka数据,使用MySQL保存偏移量

    SparkStreaming直连方式读取kafka数据,使用MySQL保存偏移量 1. ScalikeJDBC 2.配置文件 3.导入依赖的jar包 4.源码测试 通过MySQL保存kafka的偏移量 ...

  5. Geotools操作GeoJSON:解析FeatureCollection对象文件

    Geotools操作GeoJSON:解析FeatureCollection对象文件 一.解析FeatureCollection对象文件 1.1 geotools操作GeoJSON过程中的问题及相关源码 ...

  6. python中numpy库的一些使用

    想不用第三方库实现点深度学习的基础部分,发现numpy真的好难(笑),在此做点遇到的函数的笔记 惯例官方文档:https://docs.scipy.org/doc/numpy-1.16.1/refer ...

  7. docker(12)使用Dockerfile创建jenkins+python3+pytest环境

    前言 之前我们用docker手动安装了jenkins环境,在jenkins中又安装了python3环境和各种安装包,如果我们想要在其他3台机器上安装,又是重复操作,重复劳动,那会显得很low,这里可以 ...

  8. 通过HBase Observer同步数据到ElasticSearch

    Observer希望解决的问题 HBase是一个分布式的存储体系,数据按照RowKey分成不同的Region,再分配给RegionServer管理.但是RegionServer只承担了存储的功能,如果 ...

  9. 2019 ICPC 上海区域赛总结

    2019上海区域赛现场赛总结 补题情况(以下通过率为牛客提交): 题号 标题 已通过代码 通过率 我的状态 A Mr. Panda and Dominoes 点击查看 5/29 未通过 B Prefi ...

  10. Codeforces Round #682 (Div. 2)【ABCD】

    比赛链接:https://codeforces.com/contest/1438 A. Specific Tastes of Andre 题意 构造一个任意连续子数组元素之和为子数组长度倍数的数组. ...