基于element自动表单设计

3 篇文章 0 订阅
1 篇文章 0 订阅

需求是根据JSON文件生成表单,包含配置和自动model属性以及表单验证,数据回显。

目录

动态表单数据示例:

表单设置JSON示例:

表单输入JSON示例:

表单按钮JSON示例:

抛出数据示例:

动态表单示例:

HTML模板部分:

PROPS部分:

表单验证器:

事件部分:

为了数据回显

props新增defaultValue:

computed增加监听:

data中申明

组件引用示例:

HTML 部分:(导入就不说了)

效果如下:


动态表单数据示例:

(page/home/index.js)

表单设置JSON示例:

/**
 * 搜索表单设置
 * @rules:  是否验证       {Boolean}
 * @inline: 是否内联       {Boolean}
 * @width:  label宽度     {String}
 * @align:  label对齐方式  {String}
 */
const searchFormSetting = {
  rules: false,
  inline: true,
  ref: 'searchForm',
  width: '40px',
  align: 'left'
}

表单输入JSON示例:

/**
 * 搜索表单
 * @type: 输入框的类型
 * @label: 输入框的label
 * @module: 输入框的v-module属性,不写会默认咦中文首字母拼音作为改属性
 * 注:select需要配合options使用
 */
const searchFormGroup = [
  { label: '早餐', type: 'input', module: 'zaofan' },
  { label: '日期', type: 'date' },
  { label: '地点', type: 'select', options: addressOptions }
]

表单按钮JSON示例:

/**
 * 搜索表单按钮事件
 * @name: 按钮名称
 * @event: 按钮事件名(子组件直接@eventName=handleCustomizeEvent)
 * @primary:按钮类型(按钮的颜色)
 * @icon:按钮的小图标
 */
const searchFormButton = [
  { name: '查询', event: 'search', type: 'primary', icon: 'el-icon-search' },
  { name: '重置', event: 'reset', icon: 'el-icon-refresh-left' },
  { name: '一键导出', event: 'export', icon: 'el-icon-download' }
]

抛出数据示例:

export { searchFormSetting, searchFormGroup, searchFormButton}

动态表单示例:

(components/autoForm/index.vue)

HTML模板部分:

<template>
  <el-form ref="autoForm" :model="autoForm" :rules="autoRules" :label-width="setting.width" :inline="setting.inline" :label-position="setting.align" :id="setting.inline">
    <el-form-item v-for="(item, key) in form" :key="key" :label="item.label" :prop="chineseToPinYin(item.label)">
      <!--input-->
      <template v-if="item.type === 'input'">
        <template>
          <el-input v-model="autoForm[item.module || chineseToPinYin(item.label)]" :placeholder="'请输入'+item.label" @input="handleRefresh"/>
        </template>
      </template>
      <!--select-->
      <template v-if="item.type === 'select'">
        <el-select filterable v-model="autoForm[item.module || chineseToPinYin(item.label)]" :placeholder="'请选择'+item.label" @change="handleRefresh">
          <el-option v-for="(item_, key_) in item.options" :key="key+'_'+key_" :label="item_.label" :value="item_.value"></el-option>
        </el-select>
      </template>
      <!--date-->
      <template v-if="item.type === 'date'">
        <el-date-picker type="date" value-format="yyyy-MM-dd" format="yyyy-MM-dd" :placeholder="'请选择'+item.label" v-model="autoForm[chineseToPinYin(item.label)]" @change="handleRefresh"></el-date-picker>
      </template>
      <!--radio-->
      <template v-if="item.type === 'radio'">
        <el-radio-group v-model="autoForm[item.module || chineseToPinYin(item.label)]" @change="handleRefresh">
          <el-radio v-for="(item_, key_) in item.options" :key="key_" :label="item_.label" :value="item_.value"></el-radio>
        </el-radio-group>
      </template>
      <!--textarea-->
      <template v-if="item.type === 'textarea'">
        <el-input type="textarea" v-model="autoForm[item.module || chineseToPinYin(item.label)]"/>
      </template>
    </el-form-item>
    <!--BUTTON--GROUP-->
    <el-form-item v-if="button">
      <el-button v-for="(item, key) in button" :key="'btn-'+key" :class="item.float" :icon="item.icon" :type="item.type" @click="handleButton(item.event, 'autoForm')">{{ item.name }}</el-button>
    </el-form-item>
  </el-form>
</template>

PROPS部分:

props: {
    setting: {
      type: Object,
      default: () => ({
        ref: 'form',
        width: '80px',
        align: 'left'
      })
    },
    button: {
      type: Array,
      default: () => [
        { name: '查询', event: 'search', type: 'primary', icon: 'el-icon-search' },
        { name: '重置', event: 'reset', type: 'success', icon: 'el-icon-refresh-left' }
      ]
    },
    form: {
      type: Array,
      default: () => [
        { label: '类型', type: 'select' },
        { label: '分数', type: 'input' },
        { label: '时间', type: 'date' }
      ]
    }
  }

表单验证器:

    this.form.forEach(item => {
      this.autoRules[chineseToPinYin(item.label)] = verify(item)
    })
    function verify (item) {
      let rules = []
      if (item.required && item.type === 'input') {
        rules = [{ required: true, message: `请输入${item.label}`, trigger: ['blur', 'change'] }]
      } else if (item.required && item.type === 'select') {
        rules = [{ required: true, message: `请选择${item.label}`, trigger: ['blur', 'change'] }]
      } else if (item.required && item.type === 'textarea') {
        rules = [{ required: true, message: `请输入${item.label}`, trigger: ['blur', 'change'] }]
      } else if (item.required && item.type === 'date') {
        rules = [{ type: 'date', required: true, message: `请选择${item.label}`, trigger: ['blur', 'change'] }]
      } else if (item.required && item.type === 'radio') {
        rules = [{ required: true, message: `请选择${item.label}`, trigger: ['blur', 'change'] }]
      }
      return rules
    }

事件部分:

    handleButton (event, autoForm) {
      if (event === 'reset' || event === 'cancel') {
        this.autoForms = {}
      } else {
        this.$refs[autoForm].validate((valid) => {
          if (valid) {
            this.$emit(event, this.autoForms, this.setting.ref)
          } else {
            this.$message({
              type: 'warning',
              message: '请检查您的输入'
            })
          }
        })
      }
    },
    handleRefresh () {
      this.$forceUpdate()
    }

为了数据回显

props新增defaultValue:

    defaultForm: {
      type: Object,
      default: () => ({})
    }

computed增加监听:

    autoForm () {
      return this.autoForms
    }

data中申明

(注意区分autoForms和autoForm)

    return {
      autoForms: this.defaultForm
    }

组件引用示例:

(page/home/index.vue)

HTML 部分:(导入就不说了)

<auto-form :setting="searchFormSetting" :form="searchFormGroup" :button="searchFormButton" :default-form="searchForm" @search="handleClickSearchFormSearch" @export="handleClickSearchFormExport"/>

效果如下:

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值