<!--
* @Description:二次封装饿了么表单
* @Date: 2020-09-20 23:01:54 +0800
* @Author: JackChouMine
* @LastEditTime: 2020-09-21 04:00:08 +0800
* @LastEditors: JackChouMine
-->
<!--
<template>
<el-form :inline="true" :model="formInline" class="demo-form-inline">
<el-form-item label="审批人">
<el-input v-model="formInline.user" placeholder="审批人"></el-input>
</el-form-item>
<el-form-item label="活动区域">
<el-select v-model="formInline.region" placeholder="活动区域">
<el-option label="区域一" value="shanghai"></el-option>
<el-option label="区域二" value="beijing"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">查询</el-button>
</el-form-item>
</el-form>
</template>
-->
<script>
export default {
name: 'MyForm',
props: {
formList: {
type: Array,
default: () => ([])
},
formValue: {
type: Object,
default: () => ({})
}
},
data () {
return {
formData: this.convertFormValue(),
rules: this.getRules()
}
},
methods: {
convertFormValue () {
const formValue = {}
this.formList.forEach(element => {
// TODO 不要在renderInput 中处理默认值
formValue[element['key']] = element.defaultValue || ''
})
// 转换表单值后更新父组件 formValue,否则两者值不同
this.$emit('update:formValue', formValue)
return formValue
},
getRules () {
const formRules = {}
this.formList.forEach(item => {
formRules[item.key] = item.rules
})
return formRules
},
// TODO 获取表单值的接口
getFormValue () {
return this.formData
},
renderInput (h, item) {
const vm = this
const { key, placeholder = '请输入' } = item
const inputOptions = {
props: {
// TODO 在自定义组件上使用 v-model
// render 函数中使用 value + input 自定义事件
value: vm.formData[key],
clearable: true
},
attrs: {
placeholder
},
on: {
input: (value) => {
vm.formData[key] = value
// TODO update 事件实现双向绑定
vm.$emit('update:formValue', vm.formData)
}
}
}
const input = h('el-input', inputOptions)
return this.renderCol(h, input, item)
},
renderSelect (h, item) {
const vm = this
const {key, options, placeholder = '请选择', on: listeners} = item
let on = {
// TODO 想要传递 change 事件怎么办呢?
change: (value) => {
vm.formData[key] = value
vm.$emit('update:formValue', vm.formData)
}
}
if (listeners) {
on = Object.assign({}, on, listeners)
}
const selectOptions = {
props: {
value: vm.formData[key],
clearable: true,
filterable: true
},
attrs: {
placeholder
},
on
}
const optionList = options.map(item => {
return h('el-option', {props: item})
})
const select = h('el-select', selectOptions, optionList)
return this.renderCol(h, select, item)
},
renderFormList (h) {
const formItemList = []
this.formList.forEach(item => {
switch (item.type) {
case 'input':
formItemList.push(this.renderInput(h, item))
break
case 'select':
formItemList.push(this.renderSelect(h, item))
break
default:
break
}
})
return formItemList
},
// TODO 没有表单项都要被 el-col 包裹,提成函数
renderCol (h, formItem, item) {
const {key, label, span = 8} = item
const formOne = h('el-form-item', {props: {label, prop: key}}, [formItem])
return h('el-col', {props: {span}}, [formOne])
}
},
render (h) {
const itemColList = this.renderFormList(h)
const formOptions = {
props: {
inline: true,
model: this.formData,
rules: this.rules
}
}
const row = h('el-row', itemColList)
return h('el-form', formOptions, [row])
}
}
</script>
<style scoped>
</style>
还有问题,公司网络访问不了github,暂时放在这里,再去公司复制代码。