思路
首先准备一个notice.vue弹窗组件模板,之后通过调用弹窗函数的时候传入配置参数就显示不同的弹窗信息
vue创建组件实例的方法
1、render函数
2、Vue.extend()
准备一个简单的弹窗组件
notice.vue
<template>
<div class="box" v-if="isShow">
<h3>{{ title }}</h3>
<p class="box-content">
{{ message }}
</p>
</div>
</template>
<script>
export default {
data() {
return {
isShow: false
};
},
props: {
title: {
type: String,
default: ""
},
message: {
type: String,
default: ""
},
duration: {
type: Number,
default: 1000
}
},
methods: {
show(){
this.isShow= true
setTimeout(this.hide,this.duration)
},
hide(){
this.isShow= false
//隐藏弹窗的时候要销毁这个组件,调用实例上的remove方法
this.remove()
}
}
};
</script>
<style >
.box{
position: fixed;
width: 100%;
top: 16px;
left: 0;
text-align: center;
pointer-events: none;
background: #ffffff;
border: gray 3px solid;
box-sizing: border-box;
}
.box-content{
width: 200px;
margin: 10px auto;
font-size: 14x;
padding: 8px 16px;
background: #ffffff;
border-radius: 3px;
margin-bottom: 8px;
}
</style>
render函数创建弹窗
使用:
在main.js中引入,挂载到原型上
// 需要导入Notice
import create from './utils/create'
Vue.prototype.$create = create
组件内调用:需要导入Notice.vue
import Notice from "./notice";
//this.$create返回一个组件
const notice = this.$create(Notice,{
title:"hhhhh成功了呢",
message:"成功啦"
})
//show、hide 方法是在notice组件中定义的
notice.show()
create.js:
import Vue from 'vue'
// 法一:创建组件实例
function create(Component, props){
//组件构造函数如何获取
//1、 Vue.extend()
//2、render
// 借助vue创建vue实例
// vm实例会把Component当成根组件渲染出来 vm会是根组件 与#app是兄弟
const vm = new Vue({
// h是createElement 返回VNode (虚拟dom)
// 需要挂载 才能变成真实dom
render: h => h(Component,{props})
// 得到 Vue 实例后,我们需要通过一个目标元素来挂载它,有人首先会想到挂载到 #app 上,这个挂载的过程是将目标元素的内容全部替换,所以一旦挂载到 #app 上,该元素的所有子元素都会消失被替换
}).$mount() //不指定宿主元素 则会创建真实dom 但是不会追加操作 并且不能用body 界面其他元素会被覆盖
//获取真实dom: vm.$el
document.body.appendChild(vm.$el)
//返回组件实例
const comp = vm.$children[0]
// 打印出来的comp 上面也有show和hide方法 所以也页面调用的时候可以直接调用这两个方法
console.log("create -> comp", comp)
//销毁组件 实例上添加remove函数
comp.remove = function(){
document.body.removeChild(vm.$el)
vm.$destroy()
}
//返回组价实例
return comp
}
export default create
render函数以插件的形式
使用:
在main.js中引入,注册插件
// 不需要导入Notice 直接调用this.$notice({})
import create2 from './utils/create2'
Vue.use(create2)
调用:
const notice = this.$notice({
title: "hhhhh失败了呢",
message: "失败啦"
});
notice.show();
create2.js
import Vue from 'vue'
import Notice from '../components/notice'
// 法一:创建组件实例
function create(Component, props){
console.log("create -> Component", Component)
//组件构造函数如何获取
//1、 Vue.extend()
//2、render
// 借助vue创建vue实例
// vm实例会把Component当成根组件渲染出来 vm会是根组件
const vm = new Vue({
// h是createElement 返回VNode (虚拟dom)
// 需要挂载 才能变成真实dom
render: h => h(Component,{props})
}).$mount() //不指定宿主元素 则会创建真实dom 但是不会追加操作 并且不能用body 界面其他元素会被覆盖
//获取真实dom vm.$el
document.body.appendChild(vm.$el)
//返回组件实例
const comp = vm.$children[0]
//销毁组件
comp.remove = function(){
document.body.removeChild(vm.$el)
vm.$destroy()
}
return comp
}
// 使用插件
export default {
install(Vue) {
Vue.prototype.$notice = function (option) {
// 返回组件实例
return create(Notice,option)
}
// Vue.prototype.$alert = function () {}
}
}
Vue.extend()
使用:main.js引入:
import create3 from './utils/create3'
Vue.use(create3)
调用:
const notice2 = this.$notice2({
title: "hhhhh成功了呢",
message: "成功啦"
});
notice2.show();
create3.js
// 法二
import Vue from "vue";
import Notice from "../components/notice";
function create(Component, props) {
const ctor = Vue.extend(Component); //继承Vue实例
const comp = new ctor({ //创建Vue实例 实例化时可以向这个实例传入参数,但是需要注意的是 props 的值需要通过 propsData 属性来传递
propsData: props,
});
comp.$mount();
document.body.appendChild(comp.$el);
comp.remove = () => {
document.body.removeChild(comp.$el);
comp.$destroy();
};
return comp;
}
export default {
install(Vue) {
Vue.prototype.$notice2 = function(option) {
// 返回组件实例
return create(Notice, option);
};
// Vue.prototype.$alert = function () {}
},
};