用vue.extend去完成,以下有两个具体实例,
参考学习链接:
https://www.cnblogs.com/hentai-miao/p/10271652.html
以下两种方法,message.vue是一样的,不一样的是在message.js里写逻辑,第二个如果要改的话不知道怎么改逻辑
第一种(能看得懂,有遮罩层的,样式不太好看,后期用的话得修改)
新建立一个message.vue文件
// mobileTip.vue
<template>
<!-- 遮罩层 也是整个组件的容器-->
<!-- <div class="pop-container" v-if="isShow"> -->
<div class="pop-container" v-if="isShow">
<div class="message-container">
<!-- 两个icon放在一个容器中,但是只显示一个 -->
<!-- 这里的图标用的是elementUI的图标 -->
<div class="icon-container">
<div class="icon-container-success" v-if="type === 'success'">
<!-- 引用了iview的Icon组件 -->
<i class="el-icon-success icon success"></i>
</div>
<div class="icon-container-error" v-if="type === 'error'">
<!-- <Icon class="icon-close" type="md-close" size="30" color="#D8DCE9" /> -->
<i
type="md-close"
size="30"
color="#D8DCE9"
class="el-icon-error icon error"
></i>
</div>
<!-- <i class="el-icon-warning icon info" v-if="type === 'info'"></i> -->
</div>
<span class="message-text">{{ msg }}</span>
</div>
</div>
</template>
<script>
export default {
data() {
return {};
},
props: {
msg: {
type: String,
default: "",
},
type: {
type: String,
required: false,
default: "success",
},
isShow: {
// 整个遮罩和弹窗是否显示
type: Boolean,
default: true,
},
},
};
</script>
<style scoped >
.pop-container {
display: flex;
justify-content: center;
align-items: center;
z-index: 99999;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(24, 30, 53, 0.7);
backdrop-filter: blur(10px);
}
.message-container {
display: flex;
justify-content: center;
align-items: center;
min-width: 384px;
padding: 0 30px;
height: 170px;
background: #303e62;
box-shadow: 0px 0px 30px rgba(0, 0, 0, 0.1);
border-radius: 12px;
}
.icon-container {
position: relative;
height: 40px;
width: 40px;
border-radius: 50%;
//如果有less包,则可引用
/* &-error {
background-color: #fe1b1b;
height: 40px;
width: 40px;
border-radius: 50%;
.icon-close {
position: absolute;
right: 5px;
bottom: 5px;
font-weight: 900;
}
} */
/* &-success {
background-color: #4ad991;
height: 40px;
width: 40px;
border-radius: 50%;
.icon-checkmark {
position: absolute;
right: 4px;
bottom: 5px;
font-weight: 900;
}
} */
}
.message-text {
margin-left: 12px;
font-weight: 500;
font-size: 18px;
line-height: 27px;
/* 调节字体颜色 */
color: red;
}
</style>
新建立一个message.js文件
import message from './message.vue';
import Vue from 'vue'
let POPMessage = Vue.extend(message);
const MsgMain = {
show(msg, type, duration) {
// 实例化这个组件
const instance = new POPMessage();
// 将组件实例挂在到一个元素上面,如果不传参数就是挂载到body,或者也可以传入其他已经存在的元素的选择器
instance.$mount(document.createElement('div'));
// 通过组件实例的$el属性,可以访问到这个组件元素,然后把它拼接到body上。
document.body.appendChild(instance.$el);
// 给这个实例传入参数
instance.type = type;
instance.msg = msg;
instance.isShow = true;
// 设置一个延迟,过了时间弹窗消失
setTimeout(() => {
instance.isShow = false;
}, duration);
},
// 成功时调用这个方法
success(msg, duration = 2000) {
this.show(msg, 'success', duration);
},
// 失败时调用这个方法
error(msg, duration = 2000) {
this.show(msg, 'error', duration);
},
};
export function PopMsg() {
// 全局挂载
Vue.prototype.$msg = MsgMain;
// 最终调用就是this.$msg.success() 或者this.$msg.error()
}
在main.js中全局引用
import {PopMsg} from '@/views/subscribe/message'
Vue.use(PopMsg)
在页面使用
this.$msg.success('设置成功!'); // 第二个参数可以传入弹窗持续时间,默认是2000
this.$msg.success('设置成功!',3000);
this.$msg.error('设置失败!')
第二种,简单明了
新建message.vue文件
// mobileTip.vue
<template>
<div class="Box" >
<div class="contentBox">
<!-- 这里的图标用的是elementUI的图标 -->
<i class="el-icon-success icon success" v-if="type === 'success'" ></i>
<i class="el-icon-error icon error" v-if="type === 'error'" ></i>
<i class="el-icon-warning icon info" v-if="type === 'info'"></i>
<span> {{msg}}</span>
</div>
</div>
</template>
<script>
export default {
data() {
return {};
},
props: {
msg: {
type: String,
default: "",
},
type: {
type: String,
required: false,
default: "success",
},
},
};
</script>
<style scoped >
.Box{
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
overflow-x: hidden;
overflow-y: hidden;
justify-content:center;
align-items: center;
z-index: 999999;
}
.contentBox{
max-width: 80%;
min-height: 120px;
background: rgba(1,1,1,0.7);
color: rgb(221, 215, 215);
border-radius: 8px;
text-align: center;
display: flex;
flex-direction: column;
justify-content:center;
}
.contentBox span{
word-break: break-all;
margin: 0 16px;
}
.icon{
font-size: 40px;
margin-bottom: 16px;
}
.info{
color: #909399;
}
.success{
color: #67c23a;
}
.error{
color: #f56c6c;
}
</style>
在新建的message.js中
import message from './message.vue';
import Vue from 'vue'
export function PopMsg(option) {
let mobileTipComponent = Vue.extend(message);
let instance = new mobileTipComponent().$mount();
Object.assign(instance, option);
document.body.appendChild(instance.$el);
setTimeout(() => {
if(instance.$el)instance.$el.remove();
},3000)
}
['success', 'info', 'error'].forEach(type => {
PopMsg[type] = options => {
if (typeof options === 'string') {
options = {
msg: options
};
}
options.type = type;
return PopMsg(options);
};
});
在main.js中全局引用
import {PopMsg} from '@/views/subscribe/message'
Vue.prototype.$msg = PopMsg
在页面引用
// xxx.vue
// 不管在哪个组件内都可以直接调用了,不需要再单独引入。
// 调用方式如下:
//方式1:
this.$tips({
msg:'获取信息失败,请刷新页面重试',
type: 'error'
})
// 方式2:
this.$tips.error("获取信息失败,请刷新页面重试");