uniapp全局弹窗APP做全局弹窗(dialog)插件的思路
由于uniapp做的app没办法操作dom,install的dom操作都无法实现全局dialog
网上有三种方法
- 可以使用subnvue webview子窗体
- 使用 plus.nativeObj.View
- 新建一个页面进行跳转,可以实现伪弹窗(其实是打开一个背景透明的页面)
前两种工有点大,就选第三种吧。
先写一个dialog
的vue页面方在components
目录下
dialog.vue
<template>
<view>
<view class="diaglog-mask"></view>
<view class="diaglog">
<view class="diaglog-title">
{{param.title}}
</view>
<view class="diaglog-content">
<rich-text :nodes="param.content"></rich-text>
</view>
<view class="diaglog-btns">
<view class="diaglog-btns-button" :style="{color:param.cancelColor}" @click="cancelClick">
{{param.cancelText}}
</view>
<view class="diaglog-btns-button" :style="{color:param.confirmColor}" @click="confirmClick">
{{param.confirmText}}
</view>
</view>
</view>
</view>
</template>
<script>
export default {
name: "diaglog",
data(){
return {
param:{
title:'',
content:'',
cancelText:'取消',
cancelColor:'#333',
confirmText:'确定',
confirmColor:'#1ED58F',
}
}
},
onLoad(option) {
// 将参数转换成json
const data = JSON.parse(option.data)
if(data){
this.param = {...this.param,...data}
}
},
methods: {
cancelClick() {
uni.$emit('$dialog', false)
uni.navigateBack()
},
confirmClick() {
uni.$emit('$dialog', true)
}
}
}
</script>
<style lang="scss">
page {
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0);
}
.diaglog-mask {
position: fixed;
z-index: 1000;
width: 100%;
height: 100%;
left: 0;
top: 0;
background-color: rgba(0, 0, 0, .23);
}
.diaglog {
position: fixed;
width: calc(100% - 80rpx);
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
background-color: #fff;
padding-bottom: 0;
box-sizing: border-box;
z-index: 1001;
border-radius: 20rpx;
overflow: hidden;
&-title {
padding-top: 60rpx;
padding-bottom: 30rpx;
font-weight: bold;
font-size: 32rpx;
color: #333333;
text-align: center;
}
&-content {
font-weight: 500;
font-size: 28rpx;
color: #333333;
line-height: 40rpx;
padding: 0 40rpx;
padding-bottom: 60rpx;
}
&-btns {
display: flex;
position: relative;
&:before {
position: absolute;
content: '';
width: calc(100% - 80rpx);
left: 40rpx;
height: 1rpx;
background-color: #ECECEC;
}
&-button {
flex: 1;
text-align: center;
height: 100rpx;
line-height: 100rpx;
font-weight: bold;
font-size: 30rpx;
color: #333333;
&:first-child {
border-right: solid 1rpx #ECECEC;
}
&:active {
background-color: #f1f1f1;
}
}
}
}
</style>
在pages.json中加入页面
// 全局弹窗
{
"path": "components/diaglog/diaglog",
"style": {
"navigationStyle": "custom",
"app-plus": {
"animationType": "fade-in", // 设置fade-in淡入动画,为最合理的动画类型
"background": "transparent", // 背景透明
"backgroundColor": "transparent", // 背景透明
"webviewBGTransparent": true,
"mask": "none",
"popGesture": "none", // 关闭IOS屏幕左边滑动关闭当前页面的功能
"bounce": "none" // 将回弹属性关掉
}
}
}
新建plugins目录,创建dialog.js
const install = Vue => {
Vue.prototype.$dialog = (params) => {
return new Promise((resolve, reject) => {
// 防止当前页也是dialog
if (getCurrentPages()[getCurrentPages().length - 1].route == 'components/diaglog/diaglog'){
reject()
return
}
// 跳转到dialog,并且传递title,content等参数
uni.navigateTo({
url: '/components/diaglog/diaglog?data=' + encodeURIComponent(JSON.stringify(
params))
})
// 注册一个回调
uni.$once('$dialog', (state) => {
if (state) {
resolve(() => {
uni.navigateBack()
})
return
}
reject()
})
})
}
}
export default install;
在main.js中use插件
import dialogPlugin from '@/plugins/dialog';
Vue.use(dialogPlugin);
使用:
this.$dialog({
title: '用户协议和隐私政策',
content: '我们非常重视用户隐私政策并严格遵守相关的法律规定。请您仔细阅读<span style="color:#1ED58F">《隐私政策》</span>后再继续使用。如果您继续使用我们的服务,表示您已经充分阅读和理解我们协议的全部内容。并严格遵守相关的法律规定。请您仔细阅读并严格遵守相关的法律规定。请您仔细阅读。',
cancelText: '不同意',
confirmText: '同意',
}).then(()=>{
// 确认后
}).catch(()=>{
// 取消后
})