两种形式:
success:只有确定按钮
confirm:有确定和取消两种按钮,可以传入点击确定的回调函数,
代码里还加了一种 return ,只是样式不同
文字内容用的v-html便于传入不同标签显示不同颜色文字
在components文件夹下新建message文件夹,在这个文件夹下新建message.vue和index.js两个文件。
message.vue是弹窗内容。代码如下:
<template>
<div class="message fc-blue" v-if="showMessage">
<div class="message-container">
<div class="message-left">
<p class="fz-ni" v-html="text"></p>
<p class="btn-box">
<button class="btn-red btn-mm" v-if="type!='return'" @click="close()">确定</button>
<button class="btn-whi btn-mm" v-if="type=='confirm'" @click="closeSelf()">取消</button>
<button class="btn-whi btn-xl" v-if="type=='return'" @click="closeSelf()">返回</button>
</p>
</div>
<img v-if="showBg" class="message-img" src="../../assets/images/toast-img.png" />
</div>
</div>
</template>
<script>
/*
params @text: 提示内容,可为html标签+文字
params @type: 类型,默认success。
success: 成功提示框,不显示取消按钮
confirm: 确定提示框,显示取消按钮,须传callback方法
return: 返回提示框,只显示返回按钮,作用相当于取消
params @showBg:是否显示背景图,默认显示
params @showMessage:是否载入此提示框
*/
/*
调用方法:
this.$my_message({
text: "这是一个success提示",
type: "success",
});
this.$my_message({
text: "这是一个success提示",
type: "confirm",
showBg:false,
callback: this.confirm //父组件里的方法
});
*/
export default {
data() {
return {
text: "",
type: "success",
showBg: true,
showMessage: false
};
},
methods: {
close() {
this.showMessage = false;
if (this.type == "confirm") {
this.callback();
}
},
closeSelf() {
this.showMessage = false;
}
}
};
</script>
<style scoped>
.message {
position: fixed;
z-index: 100;
width: 100%;
height: 100vh;
top: 0;
left: 0;
background: rgba(0, 41, 99, 0.13);
display: flex;
justify-content: center;
align-items: center;
box-shadow: 0px 2px 9px 3px rgba(0, 0, 0, 0.23);
}
.message-container {
width: 616px;
height: 362px;
padding: 0 27px 0 27px;
background: #ffffff;
box-sizing: border-box;
display: flex;
justify-content: space-between;
}
.message-img {
margin-top: 64px;
width: 269px;
}
.message-left {
flex: 1;
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.btn-box {
margin-top: 59px;
}
.btn-whi {
margin-left: 50px;
}
.btn-whi.btn-xl{
margin-left: 0;
}
</style>
index.js的作用是将message动态挂载。
代码如下:
<template>
<div class="message fc-blue" v-if="showMessage">
<div class="message-container">
<img v-if="type=='code'" src="../../assets/images/colse.png" class="close-img" @click="closeSelf()">
<div class="message-left" v-if="type=='appointment'">
<img :src="leftImg" class="left-img">
</div>
<div class="message-right">
<img :src="img" v-if="type=='code'" class="code-img">
<div :class="type=='code'?'code-text fz-fo':'fz-ni'" v-html="text" @click="codeFn($event)"></div>
<div class="btn-box" v-if="type!='code'">
<button class="btn-red btn-mm" v-if="type!='return'" @click="close()">{{canfirmText}}</button>
<button class="btn-whi btn-mm" v-if="showCancel" @click="closeCancel()">{{cancelText}}</button>
<button class="btn-whi btn-xl" v-if="type=='return'" @click="closeSelf()">{{returnText}}</button>
</div>
</div>
<img v-if="showBg" class="message-img" src="../../assets/images/toast-img.png" />
</div>
</div>
</template>
<script>
/*
params @text: 提示内容,可为html标签+文字
params @img: 图片
params @codeCallback: 二维码底下的点击事件,用span标签
params @type: 类型,默认success。
success: 成功提示框,不显示取消按钮
confirm: 确定提示框,显示取消按钮,须传callback方法
return: 返回提示框,只显示返回按钮,作用相当于取消
code: 显示传入的二维码
params @showBg:是否显示背景图,默认不显示
params @showCancel:是否显示取消按钮,默认不显示
params @showMessage:是否载入此提示框
params @leftImg:预约课程时左边老师头像
*/
/*
调用方法:
this.$my_message.install({
text: "这是一个success提示",
type: "success",
});
this.$my_message.install({
text: "这是一个success提示",
type: "confirm",
showBg:false,
callback: this.confirm, //父组件里的方法
showCancel: true
});
*/
export default {
data() {
return {
text: "",
type: "success",
showBg: false,
showMessage: false,
showCancel: false,
canfirmText: '',
cancelText: '',
};
},
methods: {
close() {
this.showMessage = false;
document.querySelector('body').style.overflow = 'auto'
if (this.callback) {
this.callback();
}
},
closeCancel() {
this.showMessage = false;
document.querySelector('body').style.overflow = 'auto'
if (this.cancelCallback) {
this.cancelCallback();
}
},
closeSelf() {
this.showMessage = false;
document.querySelector('body').style.overflow = 'auto'
},
codeFn(e){
if(this.type=='code'){
if (event.target.nodeName == 'SPAN' && this.codeCallback){
this.codeCallback()
}
}
}
},
};
</script>
接下来是在main.js里注册全局组件。
import Message from '@/components/message/'
Vue.prototype.$my_message = Message.install;
一个全局弹窗组件就做好啦!
在父组件里调用:
this.$my_message({
text: text, //弹窗文字,可为html片段
type: 'confirm', //类型
showBg: false, //是否显示背景图
callback: this.confirm //点击确定的回调,这个方法是父组件的
});
大功告成~
2020.03.27更新: 发现浏览器回退时弹窗仍然存在,所以做了些修改:
index.js 改为:
import Vue from 'vue'
import Message from './Message.vue'
import store from '@/store/index';
const messageBox = Vue.extend(Message)
var instance = {}
Message.install = function(options, callback) {
if (options === undefined || options === null) {
options = {
text: ''
}
} else if (typeof options === 'string' || typeof options === 'number') {
options = {
text: options
}
}
if (!options.canfirmText) {
options.canfirmText = store.state.language.confirm
}
if (!options.cancelText) {
options.cancelText = store.state.language.cancel
}
options.return = store.state.language.return
instance = new messageBox({
data: options,
}).$mount()
document.body.appendChild(instance.$el)
Vue.nextTick(() => {
instance.showMessage = true;
document.querySelector('body').style.overflow = 'hidden'
})
}
Message.close = function() {
if (instance.showMessage) {
instance.closeSelf();
}
}
export default Message
增加close方法,在路由切换时关闭弹窗,router.js里增加:
router.beforeEach((to, from, next) => {
window.scrollTo(0, 0)
Message.close()
next()
})
main.js里修改一下:
Vue.prototype.$my_message = Message;
调用时:
this.$my_message.install({
text: text, //弹窗文字,可为html片段
type: 'confirm', //类型
showBg: false, //是否显示背景图
callback: this.confirm //点击确定的回调,这个方法是父组件的
});