Uni-app全局弹框提示插件
Uni-app全局弹框提示插件
由于uni-app端不支持dom操作,像下面这种方式在app端就无法实现
https://www.cnblogs.com/Plume-blogs/p/16348462.html
Uni-app端实现全局弹框插件
1.创建initPrompt.js文件(名称可以自定义,不过后面对应位置的名称要注意换过来)
代码如下:
import Vuex from 'vuex'
export default function initPrompt(v) {
// 挂在store到全局Vue原型上
v.prototype.$promptStore = new Vuex.Store({
state: {
show: true,
icon: "success", //success:成功;fail:失败
title: "标题",
desc: '内容',
duration: 3000,
btnCancelTit: '',
btnOkTit: '确定',
success: null,
},
mutations: {
hidePrompt(state) {
// 小程序导航条页面控制
// #ifndef H5
if (state.hideTabBar) {
wx.showTabBar();
}
// #endif
state.show = false
},
showPrompt(state, data) {
state = Object.assign(state, data)
state.show = true
console.log('------state====', state);
setTimeout(() => {
state.show = false
}, state.duration)
},
success(state, data) {
return state.success(state.icon)
}
}
})
// 注册$showPrompt到Vue原型上,以方便全局调用
v.prototype.$showPrompt = function(option) {
if (typeof option === 'object') {
// #ifndef H5
if (option.hideTabBar) {
wx.hideTabBar();
}
// #endif
v.prototype.$promptStore.commit('showPrompt', option)
} else {
throw "配置项必须为对象传入的值为:" + typeof option;
}
}
}
二、创建showPrompt.vue 文件
<template>
<view class="promptBox" v-show="show">
<view class="prompt">
<image v-show="icon=='success'" class="promptRipple" src="@/static/icon/ripple_succ.png" mode=""></image>
<image v-show="icon=='warn'" class="promptRipple" src="@/static/icon/ripple_warn.png" mode=""></image>
<image v-show="icon=='error'" class="promptRipple" src="@/static/icon/ripple_err.png" mode=""></image>
<!-- <image v-else class="promptRipple" src="@/static/icon/ripple_warn.png" mode=""></image> -->
<image v-show="icon=='success'" class="promptIcon" src="@/static/icon/p_succ.png" mode=""></image>
<image v-show="icon=='warn'" class="promptIcon" src="@/static/icon/p_warn.png" mode=""></image>
<image v-show="icon=='error'" class="promptIcon" src="@/static/icon/p_err.png" mode=""></image>
<!-- <image v-else class="promptIcon" src="@/static/icon/p_warn.png" mode=""></image> -->
<view class="promptTit">
{{title}}
</view>
<view class="promptDesc" v-html="desc">
</view>
<view class="pBtnBox">
<button v-show="btnCancelTit" class="pBtnCancel" @click="onCancel">{{btnCancelTit}}</button>
<button class="pBtnOk" @click="onOk('hahahhaah')">{{btnOkTit || '确定'}}</button>
</view>
</view>
</view>
</template>
<script>
export default {
name: "show-prompt",
data() {
return {
};
},
computed: {
show() {
return this.$promptStore.state.show;
},
title() {
return this.$promptStore.state.title;
},
desc() {
return this.$promptStore.state.desc;
},
icon() {
return this.$promptStore.state.icon;
},
btnCancelTit() {
return this.$promptStore.state.btnCancelTit
},
btnOkTit() {
return this.$promptStore.state.btnOkTit
},
/* iconUrl() {
var icon = this.$promptStore.state.icon
var iconUrl = ''
if(icon == 'success') {
iconUrl = '@/static/icon/p_succ.png'
}else if(icon == 'warn') {
iconUrl = '@/static/icon/p_warn.png'
}else if(icon == 'error') {
iconUrl = '@/static/icon/p_err.png'
}else {
iconUrl = '@/static/icon/p_warn.png'
}
return iconUrl
},
rippleUrl() {
var rippleUrl = ''
if(this.icon == 'success') {
rippleUrl = '@/static/icon/ripple_succ.png'
}else if(this.icon == 'warn') {
rippleUrl = '@/static/icon/ripple_warn.png'
}else if(this.icon == 'error') {
rippleUrl = '@/static/icon/ripple_err.png'
}else {
rippleUrl = '@/static/icon/ripple_warn.png'
}
return rippleUrl
} */
},
mounted() {
/* setTimeout(() => {
this.$promptStore.commit('hidePrompt')
this.$promptStore.commit('success', "confirm")
}, 3000) */
},
methods: {
onCancel() {
this.$promptStore.commit('hidePrompt')
},
onOk(res) {
this.$promptStore.commit('hidePrompt')
// this.$promptStore.commit('success', res)
this.$promptStore.commit('success')
}
},
beforeDestroy() {
this.$promptStore.commit('hidePrompt')
},
}
</script>
<style lang="scss" scoped>
.promptBox {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, .4);
z-index: 9999;
.prompt {
position: fixed;
width: 300px;
height: 234px;
border-radius: 16px;
background: linear-gradient(180deg, #e3eeff 0%, #ffffff 100%);
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
z-index: 100;
background-size: cover;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
.promptRipple {
position: absolute;
top: 0;
// width: 210px;
// height: 102px;
width: 300px;
height: 230px;
z-index: -1;
}
.promptIcon {
position: absolute;
top: 0;
transform: translateY(-50%);
width: 110px;
height: 110px;
border-radius: 90px;
overflow: hidden;
// background: linear-gradient(149.98deg, rgba(132, 181, 255, 1) 5.7%, rgba(33, 119, 250, 1) 90.23%);
// box-shadow: 0px 4px 10px rgba(18, 103, 232, 0.4);
}
.promptTit {
width: 80%;
font-size: 20px;
font-family: PingFang SC;
font-weight: 500;
color: rgba(0, 0, 0, 1);
text-align: center;
margin-top: 66px;
}
.promptDesc {
height: 40px;
margin-top: 12px;
color: rgba(102, 102, 102, 1);
font-family: PingFang SC;
font-size: 14px;
text-align: center;
}
.pBtnBox {
width: 280px;
display: flex;
justify-content: space-around;
align-items: center;
margin-top: 12px;
.pBtnOk {
width: 120px;
height: 44px;
line-height: 44px;
border-radius: 8px !important;
background: linear-gradient(301.23deg, rgba(71, 143, 253, 1) 0%, rgba(18, 103, 232, 1) 102.96%);
border: none;
color: #ffffff;
font-weight: 500;
font-size: 15px;
}
.pBtnCancel {
width: 120px;
height: 44px;
line-height: 44px;
border-radius: 8px;
background: rgba(224, 237, 255, 1);
color: rgba(18, 103, 232, 1);
font-weight: 500;
font-size: 15px;
}
}
}
}
button::after {
border: none;
}
</style>
三、在main.js文件中引入
/* 引入全局弹框组件 */
import initPrompt from "@/pages/plugin/initPrompt.js"
initPrompt(Vue);
import showPrompt from "@/pages/plugin/showPrompt.vue"
Vue.component('show-prompt',showPrompt);
四、调用
this.$showPrompt({
icon: "warn",
title: "温馨提示",
desc: '通过扣手持终端扳机读取RFID</br>请先扫RFID才能绑定',
duration: 5000,
btnOkTit: '确定',
btnCancelTit: '取消',
success: res => {
console.log('-------hahahahah---test===', res)
}
});