以 this.$message 这种 API 形式调用组件的原因:
- 使用自定义的非全局组件时,必须手动 import 和指定 components 对象属性,较为繁琐。以 API 的形式调用组件,方便快捷
- 在 vue 中,所有页面和组件最终会以 为根节点,这个根节点一般不会被限制 css position 属性,而弹窗类组件一般是绝对定位于页面中间,所以适合挂载于仅次于 的节点上 ```java // 组件实例的创建 import Vue from ‘vue’
function create(Component, props) {
// 1.创建Vue实例,Component是当前组件实例的根组件
const vm = new Vue({
// 1.1 render:虚拟DOM的实现
// 1.2 h是createElement别名,返回虚拟DOM[VNode]
// 1.3 参数props是要传递给Component的参数,{props: props, on: {click:onClick}}
// 比如:
// 2.手动挂载:使用原生dom api把它插入文档中
// 2.1 vm.$el:真实dom元素
document.body.appendChild(vm.$el)
// 3.回收:防止内存泄漏
// 3.1 vm.$children[0]获取组件实例
const comp = vm.$children[0]
comp.remove = () => {
document.body.removeChild(vm.$el)
comp.$destroy()
}
return comp
}
export default create
```java
//main.js
import Vue from 'vue'
import create from 'create.js'
Vue.prototype.$create = create
<!--MyPopup.vue-->
<template>
<div class="my-popup" v-if="isShow">
<!--弹窗遮罩-->
<div class="my-popup-bg"></div>
<!--弹窗容器-->
<div class="my-popup-ctn">
<p class="my-popup-ctt">
<span class="inner-ctt">{{message}}</span>
</p>
</div>
</div>
</template>
<script>
export default {
props: {
message: {
type: String,
default: ""
},
duration: {
type: Number,
default: 1000
}
},
data() {
return {
isShow: false
};
},
methods: {
show() {
this.isShow = true;
<!--指定一定时间间隔后自动隐藏弹窗-->
setTimeout(this.hide, this.duration);
},
hide() {
this.isShow = false;
<!--调用组件实例提供的方法销毁组件实例-->
this.remove();
}
}
};
</script>
<style lang="scss" scoped>
.my-popup {
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
.my-popup-bg {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
background: rgba($color: #000000, $alpha: 0.4);
}
.my-popup-ctn {
position: absolute;
left: 50%;
top: 50%;
width: 600px;
padding: 20px;
transform: translate(-50%, -50%);
background: rgba($color: #000000, $alpha: 0.8);
border-radius: 16px;
.my-popup-ctt {
display: flex;
min-height: 100px;
align-items: center;
justify-content: center;
.inner-ctt {
display: inline-block;
text-align: left;
font-size: 30px;
line-height: 50px;
color: #fff;
}
}
}
}
</style>
<!--TestMyPopup.vue-->
<template>
<div>
</div>
</template>
import MyPopup from "MyPopup.vue";
<script>
export default {
mounted () {
const notice = this.$create(MyPopup, {
message: '弹~弹~弹,弹走鱼尾纹',
duration: 2000
});
notice.show();
},
}
</script>