如何实现全局弹窗组件____(this.$notice({}))
弹窗这类组件的特点是它们在当前vue实例之外独⽴存在,通常挂载于body;它们是通过JS动态创建
的,不需要在任何组件中声明。常⻅使⽤姿势:
submitFrom() {
this.$refs.loginItem.validate((isValid) => {
console.log(isValid);
this.$notice({
title: "提示信息",
message: isValid ? "校验成功通过" : "不通过",
});
});
},
- create.js创建组件,利用new Vue({})中的render方法渲染组件并将组件appenChild到body中,定时自动移除,并返回组件实例
import Vue from 'vue'
export default (component, props) => {
const vm = new Vue({
render(h) {
return h(component, { props })
}
}).$mount()//生成vm实例未挂载到dom
console.log(vm)
document.body.appendChild(vm.$el)//获取dom元素
const cmop = vm.$children[0]//获取子组件实例,即notice组件
// cmop.show()
cmop.remove = () => {//为notice组件实例添加销毁方法remove
document.body.removeChild(vm.$el)
vm.$destroy()
}
return cmop
}
2.notice弹窗组件
<template>
<div class="box" v-if="isShow">
<h3>{{ title }}</h3>
<p class="box-content">{{ message }}</p>
</div>
</template>
<script>
export default {
props: {
title: {
type: String,
default: "",
},//标题
message: {
type: String,
default: "",
},//提示信息
duration: {
type: Number,
default: 3000,
},//显示时间
},
data() {
return {
isShow: false,
};
},
methods: {
show() {//显示组件
this.isShow = true;
setTimeout(this.hide, this.duration);
},
hide() {//移除组件
console.log(this);
this.isShow = false;
this.remove();
},
},
};
</script>
<style lang="scss" scoped>
.box {
position: fixed;
width: 100%;
top: 16px;
left: 0;
text-align: center;
pointer-events: none;
background-color: #fff;
border: grey 3px solid;
box-sizing: border-box;
}
.box-content {
width: 200px;
margin: 10px auto;
font-size: 14px;
padding: 8px 16px;
background: #fff;
border-radius: 3px;
margin-bottom: 8px;
}
</style>
3.将组件挂载到vue实例上面,调用show()方法显示弹窗组件
import notice from '@/components/notice';
import create from "@/utils/create";
export default {
install(Vue) {
Vue.prototype.$notice = (props) => {
const comp = create(notice, props)
comp.show()
return comp
}
}
}