需求
弹窗盒子需要挂载在body标签下,弹窗可以复用,可以使用js调换起弹窗,可以控制关闭和打开。
开干
这里以一个登录弹窗为例展示弹窗组件
第一步
声明一个属性保存弹窗实例对象
let modalObj = null;
第二步
注册一个全局弹窗组件,并留一个插槽位置填充外部内容,提高组件的可扩展性。在props中留一个value属性接受父组件传值,方便父组件控制弹窗显示。
Vue.component('Modal', {
template: `
<div class="modal" v-if="visiable">
<div class="mask"></div>
<div class="modal-wrap">
<div class="modal-main">
<div class="modal-close"></div>
<div class="modal-content">
<slot></slot>
</div>
<div class="modal-footer">
<button @click="confirm">确定</button>
<button @click="refuse">取消</button>
</div>
</div>
</div>
</div>
`,
props: {
value: {
type: Boolean,
value: false,
}
},
data(){
return {
visiable: this.value,
}
},
methods: {
close(){
// 关闭弹窗时,移除body下的弹窗元素
this.visiable = false;
modalObj && document.body.removeChild(modalObj.$el);
modalObj = null;
},
confirm(){
this.close();
},
refuse(){
this.close();
}
}
})
第三步
利用Modal写一个登录组件。
Vue.component('login-modal', {
template: `
<Modal :value="visiable">
<div>
<div>账号:<input type="number"></input></div>
<div>密码:<input type="password"></input></div>
</div>
</Modal>
`,
data(){
return {
visiable: true,
}
},
})
第四步
js渲染组件并挂载到body标签下。
function login(){
// 创建vue实例,指定组件为login-modal
const instance = new Vue({
render(h){
return h('login-modal');
},
})
// 渲染组件,$mount后就可以获取到组件的html元素对象
modalObj = instance.$mount();
// 组件的html元素对象保存在$el中,将$el挂载到body下
document.body.appendChild(modalObj.$el);
}