二次封装饿了吗表单组件

<!--
 * @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,暂时放在这里,再去公司复制代码。

原文地址:https://www.cnblogs.com/jackzhoumine/p/13703395.html