vue动态挂载组件,比如弹窗组件
- main.js:
首先创建公共js,并引入
import common from '@/utils/common'
Vue.use(common)
- confirmDialog.vue:
然后写组件的样式和方法
<template>
<div>
<el-dialog
:title="title"
:visible.sync="centerDialogVisible"
:width="width"
class="tishiDialog"
:show-close="showClose"
center
>
<div v-if="content==''" id="dialogContent">
<slot name="dialogContent" />
</div>
<div :style="contentStyle" v-html="content" />
<span slot="footer" class="dialog-footer">
<el-button v-if="cancelText!=''" @click="centerDialogVisible = false;dialogFn({cancel:true});btnClickType=1">{
{ cancelText }}</el-button>
<el-button v-if="confirmText!=''" type="primary" @click="centerDialogVisible = false;dialogFn({confirm:true});btnClickType=2">{
{ confirmText }}</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
export default {
data() {
return {
dialogFn: null,
content: '',
title: '',
width: '500px',
centerDialogVisible: false,
cancelText: '',
confirmText: '',
contentStyle: { 'text-align': 'center' },
showClose: false,
btnClickType: 0
}
},
watch: {
centerDialogVisible(value) {
if (!value) {
if (this.btnClickType == 0) {
this.dialogFn({ close: true })
}
}
}
},
methods: {
showDialog(obj) {
Object.assign(this.$data, this.$options.data.call(this))
if (obj.title) this.title = obj.title
if (obj.content) this.content = obj.content
if (obj.width) this.width = obj.width
if (obj.cancelText) this.cancelText = obj.cancelText
if (obj.confirmText) this.confirmText = obj.confirmText
if (obj.style) this.contentStyle = obj.style
if (obj.showClose) this.showClose = obj.showClose
this.centerDialogVisible = true
this.dialogFn = obj.success || (() => {})
}
}
}
</script>
- common.js:
最后动态挂载组件
export default {
install(Vue) {
this.methods(Vue)
},
methods(Vue) {
// 弹窗组件
Vue.prototype.$confirmDialog = async(obj = null) => {
if (!obj) return
const confirmDialog = (await import('@/components/dialog/confirmDialog.vue')).default
// const comp = new (Vue.extend(confirmDialog))({ propsData: props }).$mount()
const ConfirmDialogCom = Vue.component('confirmDialog', confirmDialog)// 创建组件
const confirmDialogComNew = new ConfirmDialogCom()// 创建组件实例(可以传递参数 { propsData: props })
const comp = confirmDialogComNew.$mount()// 挂载是为了把虚拟dom变成真实dom
document.body.appendChild(comp.$el)// 挂载组件
comp.$watch('centerDialogVisible', (value) => {
// 监听组件是否不显示,并删除组件、销毁组件
if (!value) {
document.body.removeChild(comp.$el)
comp.$destroy()
}
}, {
deep: true })
return comp.showDialog(obj)
}
Vue.prototype.$Other = (Component, props) => {
const vm = new Vue({
// h是createElement函数,它可以返回虚拟dom
render(h) {
console.log(h(Component, {
props }))
// 将Component作为根组件渲染出来
// h(标签名称或组件配置对象,传递属性、事件等,孩子元素)
return h(Component, {
props })
}
}).$mount() // 挂载是为了把虚拟dom变成真实dom
// 不挂载就没有真实dom
// 手动追加至body
// 挂载之后$el可以访问到真实dom
document.body.appendChild(vm.$el)
console.log(vm.$children)
// 实例
const comp = vm.$children[0]
// 淘汰机制
comp.remove = () => {
// 删除dom
document.body.removeChild(vm.$el)
// 销毁组件
vm.$destroy()
}
// 返回Component组件实例
return comp
}
}
}
- 使用
this.$confirmDialog({
title: '温馨提示',
style: { 'text-align': 'center' },
content: '保存后优惠券信息将无法二次编辑,请仔细核对!',
cancelText: '再次核对',
confirmText: '确定提交',
success: (res) => {
if (res.confirm) {
this.submitAdverForm(1)
}
}
})