vue结合element怎么快速的生成表单

代码拓霓人
• 阅读 1741

需求:怎样快速的生成表单,不用每次都去拷贝粘贴
思路:用过antd或者iView框架的都知道,参考table组件,给出一个Column和dataSource通过遍历循环的方式去生成表格,同样是否也可以给出一个2个参数去生成一个表单呢?答案显而易见是可行的,于是我写了一个FormMain的组件用来快捷是生成表单


代码如下

// FormMain.vue
<script type="text/jsx">
function noop() {}
let id = 0
export default {
  name: 'FnFormMain',
  props: {
    asyncProps: Object,
    data: {
      type: Object,
      default: () => { return {} }
    },
    config: {
      type: Array,
      default: () => {
        return []
      }
    }
  },
  data() {
    return {
      dictionaryData: {
      },
      propsAttar: {}
    }
  },
  computed: {
  },
  created() {
    let arr = ['select', 'radio', 'checkbox']
    this.config.map(el => {
      let isArray = Array.isArray(el)
      if (isArray) {
        el.map(l => {
          if (arr.indexOf(l.type) >= 0) {
            this.setProps(l)
          }
        })
      } else if (arr.indexOf(el.type) >= 0) {
        this.setProps(el)
      }
    })
  },
  methods: {
    remoteMethod() {
      debugger
    },
    handleAvatarSuccess(url, file, key) {
      this.data[key] = url
      this.onUploadSuccess(url, file)
    },
    beforeUploadFile(file) {
      this.beforeUpload(file)
    },
    setProps(el) {
      let { async, key, data = [] } = el
      if (async) {
        this.$set(this.propsAttar, key, [])
        async(key).then(res => {
          el.data = this.propsAttar[key] = res
        })
      } else {
        el.data = this.propsAttar[key] = typeof data === 'string' ? this.dictionaryData[data] : data
      }
    },
    formatHtml(el, key, createElement) {
      let relust
      let { disabled } = el

      let isDisabled = disabled ? disabled.value === undefined ? !!this.data[disabled.key] : this.data[disabled.key] === disabled.value : false

      switch (el.type) {
        case 'select':
          if (el.data || this.propsAttar[key]) {
            if (!el.data) {
              relust = ''
              return
            }
            relust = (
              <el-select disabled={isDisabled} multiple={el.multiple} allow-create={el.allowCreate} default-first-option remote={el.remote} remote-method={(value) => {
                el.remoteMethod(value, el)
              }} clearable filterable={el.filterable} v-model={this.data[key]} placeholder={`请选择${el.label}`}>
                {
                  el.group
                    ? el.data.map(e =>
                      <el-option-group label={e.label} key={e.value}>
                        {
                          e.children.map(subEl => <el-option label={subEl.label} value={subEl.value}> </el-option>)
                        }
                      </el-option-group>
                    )
                    : el.data.map(subEl => <el-option label={subEl.label} value={subEl.value}></el-option>)
                }
              </el-select>
            )
          } else {
            relust = '字段数据不存在'
          }
          break
        case 'input':
          relust = (
            <el-input placeholder={`请输入${el.label}`} v-model={this.data[key]}></el-input>
          )
          break
        default:
          break
      }
      return relust
    }
  },
  render(createElement) {
    const component = (
      <div>
        {
          this.config.map(el => {
            let isArray = Array.isArray(el)
            let { key, labelWidth, label, show } = isArray ? el[0] : el
            let relust = ''
            if (isArray && (el[0] && el[0].col)) {
              relust = []
              el.forEach((item, index) => {
                let { key, labelWidth, label, show } = item
                relust.push(
                  <el-col span={12}>
                    <el-form-item v-show={show ? (this.data[show.key] === show.value) : true} label-width={labelWidth} prop={key} label={ labelWidth === undefined || labelWidth !== '0' ? label : '' }>
                      {
                        this.formatHtml(item, item.key, createElement)
                      }
                    </el-form-item>
                  </el-col>
                )
              })

              return (
                <el-row gutter={10}>
                  {relust}
                </el-row>
              )
            } else if (isArray) {
              relust = []
              let len = el.length
              el.forEach((item, index) => {
                relust.push(
                  <el-col span={11}>
                    {
                      this.formatHtml(item, item.key, createElement)
                    }
                  </el-col>
                )
                if (index < len - 1) {
                  relust.push(
                    <el-col class="text-center" span={2}> - </el-col>
                  )
                }
              })
            } else {
              relust = this.formatHtml(el, key, createElement)
            }
            return (
              <el-form-item v-show={show ? Array.isArray(show) ? show.reduce((a, b) => { return a && this.data[b.key] === b.value }, true) : (this.data[show.key] === show.value) : true} label-width={labelWidth} prop={key} label={ labelWidth === undefined || labelWidth !== '0' ? label : '' }>
                {relust}
              </el-form-item>
            )
          })
        }
      </div>
    )
    return component
  },
  watch: {
  }
}

</script>
// template
<div id="app">
    <el-form ref="form" :model="data" style="width: 460px;" label-width="80px">
        <FormMain :config="config" :data="data"></FormMain>
    </el-form>
</div>
import FormMain from "./components/FormMain";

export default {
    name: "App",
    components: { FormMain },
    data() {
        return {
            config: [
            { label: "A", type: "input", key: "a", labelWidth: "80px" },
            {
                label: "BB", type: "radio",
                key: "d",
                data: [ { label: "x", value: 1 },
                    { label: "y", value: 2 },
                    { label: "z", value: 3 }
                ]
            },
            { 
                label: "B",
                type: "select",
                key: "b",
                async: this.asyncData
            },
            { label: "C", tip: "这是C", type: "input", key: "c" },
            [

                {

                label: "日期范围",

                type: "date",

                key: "beginDate",

                tip: "结束时间没有填写则以最近天数为准,填写结束时间则最近天数失效"

                },

                { label: "结束日期", type: "date", key: "endDate" }
            ]
            ],
            data: {
                a: 1,
                b: 2,
                c: 3,
                d: 1,
                beginDate: new Date(),
                endDate: new Date()
            }
        };
    },
    methods: {
        asyncData() {
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    resolve([
                        { label: "A", value: 1 },
                        { label: "B", value: 2 },
                        { label: "C", value: 3 }
                    ]);
                }, 1000);
            });
        }
    }
};

支持:

  • select radio,checkbox异步请求数据
  • label提示信息
  • 一列多个输入框
  • 指定label宽度

可以点击查看实例 demo链接

vue结合element怎么快速的生成表单

点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Wesley13 Wesley13
4年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Easter79 Easter79
4年前
vue+element 表格formatter数据格式化并且插入html标签
前言   vue中element框架,其中表格组件,我既要行内数据格式化,又要插入html标签一贯思维,二者不可兼得也一、element表格数据格式化  !(https://oscimg.oschina.net/oscnet/3c43a1cb3cbdeb5b5ad58acb45a42612b00.p
Easter79 Easter79
4年前
swap空间的增减方法
(1)增大swap空间去激活swap交换区:swapoff v /dev/vg00/lvswap扩展交换lv:lvextend L 10G /dev/vg00/lvswap重新生成swap交换区:mkswap /dev/vg00/lvswap激活新生成的交换区:swapon v /dev/vg00/lvswap
LeeFJ LeeFJ
3年前
Foxnic-Web 代码生成 (6) —— 配置字段的表单组件
上一篇中我们讲述了字段配置的通用项,本篇将详细介绍字段的表单编辑器配置。针对不同的表单编辑器,可以指定不同的代码生成参数。默认情况下,代码生成会根据表字段的类型等信息自动匹配一个表单组件。当然,开发人员也可以手动指定每个字段的表单组件类型。  虽然表单组件是呈现在表单界面的,但是它的设置同样会影响搜索区域对应的条件输入框。搜索区域的条件输入框组件按一定的规则与表单组件对应。本文将逐个介绍表单组件以及它们的代码生成配置项。
【ReportDesign】100行代码搞定一个功能完整的报表页,你不心动吗?
使用文档地址:http://43.143.54.159/github地址:https://github.com/hunanliy/reportdesignReportDesign是一款基于ElementUI进行扩展的Vue开源组件库,以数据驱动视图,通过简单的配置生成一个完整的页面,主要包含Form表单、Table表格、Report报表和DialogS
Stella981 Stella981
4年前
Antd Vue 表单生成快速开发指南
之前发布了一款基于Element的表单设计器,可以快速设计和生成表单,设计器地址:http://form.making.link/(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fform.making.link%2F)。现在我可以告诉大家,Antd表单支持来了,可以使用设计器设计好表单后
Stella981 Stella981
4年前
Python+Selenium自动化篇
本篇文字主要学习selenium定位页面元素的集中方法,以百度首页为例子。0.元素定位方法主要有:id定位:find\_element\_by\_id('')name定位:find\_element\_by\_name('')class定位:find\_element\_by\_class\_name(''
Easter79 Easter79
4年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移