推荐设备MORE

静态网页制作

静态网页制作

行业知识

小程序直播带货_使用Vue构造器创建Form组件的通用

日期:2021-01-08
我要分享
利用Vue构造器创建Form组件的通用解决方法       这篇文章主要给大家介绍了关于利用Vue构造器创建Form组件的通用解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

前言

在前端平常的业务中,无论是官网、展示页还是后台运营系统都离不开表单,它承载了大部分的数据采集工作。所以如何更好地实现它,是平常工作中的一个重要问题。

在应用Vue框架去开发业务时,会将页面上每个独立的可视/可交互区域拆分为一个组件,再通过多个组件的自由组合来组成新的页面。例如

 template 
 header /header 
 content /content 
 footer /footer 
 /template 

当用户的某个行为触发表单时(例如注册、建立内容等),期望在页面中弹出一个From组件。通常的做法是在template中填入一个 form 组件用于开发,并通过控制data中的UI.isOpen来对其display进行控制,例如在当前 template 组件内开发

 template 
 header /header 
 content /content 
 footer /footer 
 register-form v-if="UI.isOpen" 
 form-item /form-item 
 submit-button /submit-button 
 /register-form 
 /template 

这样开发有一点优势,Form组件与其父组件之间可以通过prop以及$emit方便通信。但是也会有以下几个缺陷:

当前组件的data必须要有UI.isOpen来控制表单,如果存在多个表单时,就会有大量的状态来维护表单的开关; 如果表单多次弹出时,可能需要对表单的data进行重置; 与组件化思想相违背,表单不属于当前页面,它只是由于用户行为触发的结果。

为了解决以上缺陷,并且还能具备方便通信的优势,本文选择用Vue.extend将原有 form 组件转化为method function,并维护在当前组件的method中,当用户触发时,在页面中挂载,关闭时自动注销。

实例

APP组件

 template 
 div id="app" 
 el-button 
 type="primary" icon="el-icon-edit-outline"
 @click="handleClick"
 注册 /el-button 
 /div 
 /template 
 script 
import register from './components/register'
import { transform } from './transform'
export default {
 name: 'App',
 methods: {
 register: transform(register),
 handleClick () {
 this.register({
 pro凡科抠图Data: { name: '皮鞋' },
 done: name = alert(`${name}牛B`)
 /script 

当 el-button 的点击事件触发时,调用register方法,将表单组件挂载在页面中。

Form组件

 template 
 div v-if="isVisible" 
 div 
 i @click.stop="close" /i 
 ... header / 
 ... content / 
 div 
 el-button 
 type="primary"
 @click="handleClick"
 确定 /el-button 
 el-button 
 type="primary"
 @click="handleClick"
 取消 /el-button 
 /div 
 /div 
 /div 
 /template 
 script 
export default {
 por凡科抠图: { ... },
 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函数,它将原有的`ponents转化为了method function,其原理如下

const transform = (component) = {
 const _constructor = ponent)
 return function (options = {}) {
 const {
 pro凡科抠图Data
 } = options
 let instance = new _constructor({
 pro凡科抠图Data
 }).$mount(document.createElement('div'))
 return instance
}

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

const _constructor = ponent)

然后return function,它的功能是:

将 form / 组件转化为method 在method调用时,将组件实例化并传递pro凡科抠图Data

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

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

有了挂载,就必须要有注销。对应的生命周期应该是destroyed,所以

method: {
 destroyElement () {
 this.$destroy()
destroyed () {
 this.$el.parentNode.removeChild(this.$el)
}

组件注销的时间与它在页面中显示息息相关,当 form / 在页面中不可见时候,需要注销它

method: {
 destroyElement () {
 this.$destroy()
destroyed () {
 this.$el.parentNode.removeChild(this.$el)
}

一般Form组件有两个功能:

done:代表用户确认; cancel:代表用户取消;

当done或cancel触发时,APP组件内可能会有相应的变化,所以在组件实例化之后,利用$on去监听对应的done事件以及cancel事件。

done inlineListen({
 method: 'done',
 options,
 instance
cancel inlineListen({
 method: 'cancel',
 options,
 instance
})

其中inlineListen函数可以方便后续添加其他的event,其代码为

const inlineListen = ({
 method,
 options,
 instance
}) = {
 let listener = `on${method}`
 instance[listener] = options[method]
 instance.$on(method, function (data) {
 this[listener](data)
}

也可以将上述方案封装成Promise形式,如下

export const transform = (component) = {
 const _constructor = ponent)
 return function (options = {}) {
 const {
 pro凡科抠图Data
 } = options
 return new Promise((resolve, reject) = {
 let instance = new _constructor({
 pro凡科抠图Data
 }).$mount(document.createElement('div'))
 instance.$on('done', data = resolve(data))
}

使用

可以将上述属于 Form/ 公有的data以及method独立出来,再通过mixins引入到每个表单内,例如

export default {
 data() {
 return {
 visible: true
 watch: {
 visible(newValue) {
 if (!newValue) {
 this.destroyElement()
 mounted() {
 document.body.appendChild(this.$el)
 destroyed() {
 this.$el.parentNode.removeChild(this.$el)
 methods: {
 destroyElement() {
 this.$destroy()
 close() {
 this.visible = false
}

再通过mixins混入。

 script 
import popupWin from '../mixins/popup-win'
export default {
 mixins: [popupWin],
 data () {
 return {
 input: '',
 gender: 1
 methods: {
 handleClick ({ type }) {
 const handler = {
 close: () = this.close(),
 confirm: () = {
 const { input } = this
 this.$emit('done', input)
 /script 

调用时,只需

export default {
 name: 'App',
 methods: {
 register: transform(register),
 handleClick () {
 this.register({
 pro凡科抠图Data: {
 // done: data = function
 done () {
 // 外部关闭
 this.close()
}

凡科抠图:如果业务场景需要,在外部控制表单的关闭时,只需要改变done function的context,也就是this指针指向 Form/ 。

总结

通过上述的transform函数,将原有的注入式组件转化为了命令式,简化了页面状态的维护,在通过mixins混入公有data以及method,简化了表单组件开发。上述方法也可用于开发toast、alert、confirm等组件,只需要将
Vue.prototype.method = transform(Toast-Component)

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对凡科的支持。