前言

成都創(chuàng)新互聯(lián)公司專業(yè)為企業(yè)提供象州網站建設、象州做網站、象州網站設計、象州網站制作等企業(yè)網站建設、網頁設計與制作、象州企業(yè)網站模板建站服務,十余年象州做網站經驗,不只是建網站,更提供有價值的思路和整體網絡服務。
在前端平常的業(yè)務中,無論是官網、展示頁還是后臺運營系統(tǒng)都離不開表單,它承載了大部分的數(shù)據(jù)采集工作。所以如何更好地實現(xiàn)它,是平常工作中的一個重要問題。
在應用Vue框架去開發(fā)業(yè)務時,會將頁面上每個獨立的可視/可交互區(qū)域拆分為一個組件,再通過多個組件的自由組合來組成新的頁面。例如
<template> <header></header> ... <content></content> ... <footer></footer> </template>
當用戶的某個行為觸發(fā)表單時(例如注冊、建立內容等),期望在頁面中彈出一個From組件。通常的做法是在template中填入一個<form>組件用于開發(fā),并通過控制data中的UI.isOpen來對其display進行控制,例如在當前<template>組件內開發(fā)
<template> <header></header> ... <content></content> ... <footer></footer> ... <register-form v-if="UI.isOpen"> <form-item></form-item> ... <submit-button></submit-button> </register-form> </template>
這樣開發(fā)有一點優(yōu)勢,F(xiàn)orm組件與其父組件之間可以通過prop以及$emit方便通信。但是也會有以下幾個缺陷:
為了解決以上缺陷,并且還能具備方便通信的優(yōu)勢,本文選擇用Vue.extend將原有<form>組件轉化為method function,并維護在當前組件的method中,當用戶觸發(fā)時,在頁面中掛載,關閉時自動注銷。
實例
演示地址:演示實例
代碼地址:FatGe github (本地下載)
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({
propsData: { name: '皮鞋' },
done: name => alert(`${name}牛B`)
})
}
}
}
</script>當<el-button>的點擊事件觸發(fā)時,調用register方法,將表單組件掛載在頁面中。
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>組件的狀態(tài),其打開或關閉只維護在自身的data中。
原理
上述代碼中,最為關鍵的一步就是transform函數(shù),它將原有的`從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)創(chuàng)建一個<Form/>組件的子類
const _constructor = Vue.extend(component)
然后return function,它的功能是:
const {
propsData
} = options
let instance = new _constructor({
propsData
}).$mount(document.createElement('div'))為了能夠控制實例化后的組件,選擇instance返回。
當組件實例化時,它只是掛載到document.createElement('div')上,但是并沒有掛載到頁面上,所以需要將其appendChild到頁面中。為了更好的語義化,選擇在組件的生命周期中完成它在頁面中的掛載。實例化時,會觸發(fā)組件mounted生命周期,所以當其觸發(fā)時可以掛載在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觸發(fā)時,APP組件內可能會有相應的變化,所以在組件實例化之后,利用$on去監(jiān)聽對應的done事件以及cancel事件。
done && inlineListen({
method: 'done',
options,
instance
})
cancel && inlineListen({
method: 'cancel',
options,
instance
})其中inlineListen函數(shù)可以方便后續(xù)添加其他的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 = Vue.extend(component)
return function (options = {}) {
const {
propsData
} = options
return new Promise((resolve, reject) => {
let instance = new _constructor({
propsData
}).$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({
propsData: {
...
},
// done: data => function
done () {
// 外部關閉
this.close()
}
})
}
}
}PS:如果業(yè)務場景需要,在外部控制表單的關閉時,只需要改變done function的context,也就是this指針指向<Form/>。
總結
通過上述的transform函數(shù),將原有的注入式組件轉化為了命令式,簡化了頁面狀態(tài)的維護,在通過mixins混入公有data以及method,簡化了表單組件開發(fā)。上述方法也可用于開發(fā)toast、alert、confirm等組件,只需要將Vue.prototype.method = transform(Toast-Component)
好了,以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對創(chuàng)新互聯(lián)的支持。
標題名稱:利用Vue構造器創(chuàng)建Form組件的通用解決方法
網頁鏈接:http://chinadenli.net/article14/geigge.html
成都網站建設公司_創(chuàng)新互聯(lián),為您提供定制開發(fā)、手機網站建設、、網站設計、小程序開發(fā)、企業(yè)建站
聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)