利用Vue构造器创建Form组件的通用解决方法

2020-06-13 10:43:19易采站长站整理

Form组件


<template>
<div class="mock" v-if="isVisible">
<div class="form-wrapper">
<i class="el-icon-close close-btn" @click.stop="close"></i>

...<header />
...<content />

<div class="footer">
<el-button
type="primary"
@click="handleClick"
>确定</el-button>

<el-button
type="primary"
@click="handleClick"
>取消</el-button>
</div>
</div>
</div>
</template>

<script>
export default {
porps: { ... },

data () {
return {
isVisible: true
}
},

watch: {
isVisible (newValue) {
if (!newValue) {
this.destroyElement()
}
}
},

methods: {
handleClick ({ type }) {
const handler = {
close: () => this.close()
}
},
destroyElement () {
this.$destroy()
},
close () {
this.isVisible = false
}
},

mounted () {
document.body.appendChild(this.$el)
},

destroyed () {
this.$el.parentNode.removeChild(this.$el)
}
}
</script>

在APP组件内并未维护<form>组件的状态,其打开或关闭只维护在自身的data中。

原理

上述代码中,最为关键的一步就是transform函数,它将原有的`从single-file components转化为了method function,其原理如下


const transform = (component) => {
const _constructor = Vue.extend(component)
return function (options = {}) {
const {
propsData
} = options
let instance = new _constructor({
propsData
}).$mount(document.createElement('div'))
return instance
}
}

首先利用Vue.extend(options)创建一个<Form/>组件的子类


const _constructor = Vue.extend(component)

然后return function,它的功能是:

将<form />组件转化为method
在method调用时,将组件实例化并传递propsData


const {
propsData
} = options
let instance = new _constructor({
propsData
}).$mount(document.createElement('div'))

为了能够控制实例化后的组件,选择instance返回。

当组件实例化时,它只是挂载到document.createElement(‘div’)上,但是并没有挂载到页面上,所以需要将其appendChild到页面中。为了更好的语义化,选择在组件的生命周期中完成它在页面中的挂载。实例化时,会触发组件mounted生命周期,所以当其触发时可以挂载在document.body中,具体如下


mounted () {