如何像Element中的Notification通知组件一样在js代码中就能调用显示呢,项目改造使用了vuetify组件但是它的Notification组件没有提供js api所以只能自己撸一个了。
直接看Element Notification组件的源码,照葫芦画瓢,它可以我就可以。

发现源码中定义了两个文件,一个是js一个是vue的模板,模板文件自然不用多说,关键就在于这个main.js。
import Main from './main.vue';
const NotificationConstructor = Vue.extend(Main);
//省略若干行代码
instance = new NotificationConstructor({
data: options
});
if (isVNode(options.message)) {
instance.$slots.default = [options.message];
options.message = 'REPLACED_BY_VNODE';
}
instance.id = id;
instance.$mount();
document.body.appendChild(instance.$el);
instance.visible = true;
instance.dom = instance.$el;
instance.dom.style.zIndex = PopupManager.nextZIndex();阅读源码发现实现步骤如下:
1、导入模板文件然后使用Vue.extend继承得到子类NotificationConstructor;
2、创建一个NotificationConstructor的一个实例(完整的Vue实例,可以调用生命的方法,访问data中的属性等...),instance;
3、instance调用$mount()手动挂载;
4、将$el放到body上就可以显示了。
最后实现基于vuetify的Notification组件,源码如下:
1、vue组件
<template>
<v-snackbar v-model="snackbar" top vertical :color="color" :timeout="5000">
<div class="snackbar-content">{{ message }}</div>
<v-btn text @click="snackbar = false" class="snackbar-close-btn">
关闭
</v-btn>
</v-snackbar>
</template>
<script>
export default {
name: "notification",
data() {
return {
snackbar: false,
status: "",
message: "",
onClose: () => {}
};
},
computed: {
color() {
let color;
//下面的bg-success样式需要自己提供,vuetify没有提供对应的样式
switch (this.code) {
case "ok":
color = "bg-success";
break;
case "fail":
color = "bg-error";
break;
case "error":
color = "bg-error";
break;
case "warning":
color = "bg-warning";
break;
case "forbidden":
color = "bg-warning";
break;
case "missing":
color = "bg-warning";
break;
case "invalid":
color = "bg-error";
break;
default:
color = "bg-default";
}
return color;
}
},
watch: {
snackbar(currVal) {
if (!currVal && typeof this.onClose === "function") {
this.onClose();
}
}
},
methods: {
setOptions(options) {
this.snackbar = true;
this.status= options.status;
this.message = options.message;
this.onClose = options.onClose;
}
}
};
</script>
<style scoped>
.snackbar-content {
word-break: break-all;
}
.snackbar-close-btn {
margin-top: 0 !important;
}
</style>2、我这里并没有像element一样使用多实例显示,我只使用了一个实例(多次调用页面上也只会显示一个消息框)
import Vue from "vue";
import Index from "./index.vue";
const NotificationConstructor = Vue.extend(Index);
let instance = new NotificationConstructor();
instance.$mount();
document.body.appendChild(instance.$el);
instance.visible = true;
instance.dom = instance.$el;
const Notification = function(options) {
options = options || {};
instance.setOptions(options);
};
//快捷调用方法
["ok", "fail", "error", "warning", "forbidden", "missing", "invalid"].forEach(
code => {
Notification[code] = (options, onClose) => {
if (typeof options === "string") {
options = {
message: options,
onClose: onClose
};
}
options.code = code;
return Notification(options);
};
}
);
export default Notification;3、在main.js中导入,并使用
import Notification from "@/components/notification"; Vue.prototype.$notify = Notification;
4、在其他vue组件中调用
this.$notify.ok("some message")
this.$notify.fail("some message")
this.$notify.missing("some message")
...5、弄完后我想起了vue官网的一句话:“下图展示了实例的生命周期。你不需要立马弄明白所有的东西,不过随着你的不断学习和使用,它的参考价值会越来越高。"
