happened to have an article: Vue plug-ins and extend methods
To put it simply, write a $toash method on the prototype of Vue:
Vue.prototype.$toash = function (desc) {}
and you can use it
this.$toash ("text description")
within the component.
then, in the declaration $toash
method, all you have to do is take the parameters, generate a piece of dom, and manually document.body.appendChild (), to insert the toash into the page. And reasonably control the hiding of this piece of dom. The logic depends on your needs.
the blog post is my own notes, which may not be written in detail. You can check (xi) element UI's $message source code ;
in (chao).
recently I have been drawing the ui component of vue, and there is a message component, which is similar to yours. To put it simply, the difficulty of such components is:
- use Vue.extend instead of writing components in html
- needs to implement a singleton pattern
many frameworks have two files for such components, one xxx.vue, and one xxx.js.
message.vue
<template>
<div :class="['jn-message','jn-message-'+icon]" :style="{'z-index':ZINDEXPP}">
<i :class="['jn-icon-'+icon,'jn-message-icon']" v-if="icon"></i>
<div class="jn-message-content">
<template v-if="htmlEnable">
<div v-html="$slots.default[0]" class="jn-message-content" >
</div>
</template>
<template v-else>
<slot>
</slot>
</template>
</div>
<i v-if="closeButton" class="jn-message-close jn-icon-close" @click="closeMessage"></i>
</div>
</template>
<script>
import {ZINDEX} from '@/js/utils/const.js'
export default {
name: "jn-message",
data(){
return {
ZINDEX
}
},
mounted() {
setTimeout(() => {
this.close();
}, this.delay);
},
props: {
delay: {
type: Number,
default: 3000
},
htmlEnable: {
type: Boolean,
default: false
},
closeButton:{
type:Boolean,
default:false
},
callback:{
type:Object
},
icon: {
type: String,
default: "info"
}
},
methods: {
close() {
this.$el.remove();
this.$emit("close");
this.$destroy();
},
closeMessage() {
var beforeClose = this.callback.beforeClose,
afterClose = this.callback.afterClose
beforeClose && beforeClose.call(this, this);
this.close();
afterClose && afterClose.call(this, this);
}
}
};
</script>
<style lang="scss">
@import "../../../css/message.scss";
</style>
message.js
import Vue from 'vue';
import Message from './message.vue';
import {mergeDeep} from '@/js/utils/tools.js'
let MessageConstructor = Vue.extend(Message);
const message = function () {
var instance = null,
uid = null
return function (option) {
if(typeof option == 'string'){
option = {
text: option
}
}
var config = mergeDeep({
props: {
htmlEnable: false,
},
text: 'default'
}, option)
if (!instance || instance._uid != uid) {
if (!instance) {
instance = new MessageConstructor({
propsData: config.props
})
uid = instance._uid
} else {
let t = new MessageConstructor({
propsData: config.props
})
if (t._uid != uid) {
instance.closeMessage()
instance = t
uid = t._uid
}
}
instance.$slots.default = [config.text]
instance.$mount()
instance.$on('close', function () {
instance = null
uid = null
})
document.body.appendChild(instance.$el)
}
return instance
}
}
const plugin = {}
plugin.install = function (Vue, options) {
Vue.prototype.$message = message()
}
export default plugin;
vue component is mounted to the global method refer to