一、存在及需要解决的问题

一般在做后台OA的时候会发现表单重复代码比较多,且逻辑基本一样,每次新加一个表单都需要拷贝基本一致的代码结构,然后只是简单地修改对应的字段进行开发

二、预期结果

提取重复的表单逻辑形成通用的组件,通过约定的JSON数据结构配置生成表单

1、使用方法

  1. <common-form :form-option="formOption" :is-reset-form-flag="isResetFormFlag"></common-form>
  2. 复制代码

接收的props:

isResetFormFlag:是否更新表单内容标志,用于触发更新表单的formModel

formOption:表单配置,下有详细配置说明

isDisabled:表单是否可编辑

2、单一表单组配置

  1. {
  2. name: 'channel-form',
  3. data: {},
  4. items: [
  5. {
  6. label: '类型',
  7. name: 'biz_type',
  8. type: 'select',
  9. dataList: [{
  10. index: 1,
  11. text: '业务部'
  12. }]
  13. }
  14. ],
  15. rules: {
  16. name: [{ required: true, message: '请输入产品名称', trigger: 'blur' }]
  17. },
  18. btnList: [{
  19. text: '保存',
  20. type: 'primary',
  21. onClick: this.commitForm
  22. }]
  23. }
  24. 复制代码

3、多表单组配置

  1. formOption: {
  2. name: 'channel-form',
  3. data: {},
  4. groups: [{
  5. title: '',// 组标题
  6. tips: ''// 组提示
  7. items: [] // 组表单项,和单一组配置一致
  8. }]
  9. }
  10. 复制代码

三、实现逻辑

根据配置输出不同的form-item,需要特殊处理的表单项通过jsx由使用的地方自定义实现

什么是JSX:cn.vuejs.org/v2/guide/re…

文档:egoist.moe/2017/09/21/…

使用JSX原因:表单包含了大部分的选项,但是也有很多不确定的情况需要依赖外部自己实现,相对于template的方式jsx使用起来更加灵活

四、配置文档

节点 描述 类型 是否必须 备注
name 表单名 String 默认名 oa-form
data 表单数据 Object 用于编辑场景异步请求的表单填充数据
groups 表单组 Array groups 和 items 不应该同时存在,groups 中包含了items,如果groups为空取外部的items渲染,groups不为空仅渲染groups组内容
items 表单项 Array 支持的type类型:输入框:input、textarea;多选框:checkbox;单选框:radio;下拉菜单:select
rules 表单校验规则 Object 节点名需要与items配置的name一一对应
btnList 按钮列表 Array 会在回调函数包含表单的数据及表单引用

六、VUE JSX 遇到的一些问题

v-model支持: babel-plugin-jsx-v-model

sync 修饰符写法

  1. visible={ this.dialogImgVisible } {...{on: {'update:visible': (val) => { this.dialogImgVisible = val }}}}
  2. 复制代码

七、部分实现代码

1、生成列表

  1. generateList (itemObj) {
  2. let itemEle = []
  3. for (let index = 0; index < itemObj.dataList.length; index++) {
  4. const item = itemObj.dataList[index]
  5. switch (itemObj.type) {
  6. // 下拉菜单
  7. case 'select':
  8. itemEle.push(<el-option key={ item.index } label={ item.text } value={ item.index }></el-option>)
  9. break
  10. // 多选框
  11. case 'checkbox':
  12. itemEle.push(<el-checkbox label={ item.index }>{ item.text }</el-checkbox>)
  13. break
  14. // 单选框
  15. case 'radio':
  16. itemEle.push(<el-radio label={ item.index }>{ item.text }</el-radio>)
  17. break
  18. }
  19. }
  20. return itemEle
  21. }
  22. 复制代码

2、生成下拉菜单

  1. generateSelect (item) {
  2. return <el-select v-model={ this.formModel[item.name] } style={ item.style || this.defaultStyle }>{ this.generateList(item) }</el-select>
  3. }
  4. 复制代码

备注:其他项实现类似

3、render函数

  1. render (h) {
  2. let ele = []
  3. // 表单内容
  4. if (this.isGroup) {
  5. ele = this.generateGroup()
  6. } else {
  7. ele = this.generateFormItems(this.formOption.items)
  8. }
  9. // 按钮列表
  10. let btnListEle = []
  11. this.formOption.btnList.forEach((btn) => {
  12. btnListEle.push(<el-button type={ btn.type } on-click={ () => { btn.onClick(this.$refs[this.formName], this.formModel) } }>{ btn.text }</el-button>)
  13. })
  14. return (
  15. <div class="oa-form-container">
  16. <el-form ref={ this.formName } model={ this.formModel } rules={ this.formOption.rules } inline={ this.inline } disabled={ this.isDisabled } label-width={ this.formOption.labelWidth || '150px'}>
  17. { ele }
  18. <el-form-item label-width={ this.isGroup ? '0' : '150px'}>{ btnListEle }</el-form-item>
  19. </el-form>
  20. </div>
  21. )
  22. }
  23. 复制代码

八、最后贴一个表格的封装

  1. <script>
  2. export default {
  3. props: {
  4. // 表格列
  5. columns: {
  6. type: Array,
  7. default: _ => { return [] }
  8. },
  9. // 表格数据
  10. tableData: {
  11. type: Array,
  12. default: _ => { return [] }
  13. },
  14. // loading 标志
  15. loading: {
  16. type: Boolean,
  17. default: false
  18. }
  19. },
  20. methods: {
  21. sortChange (obj) {
  22. this.$emit('sortChange', obj)
  23. }
  24. },
  25. render () {
  26. return (
  27. <el-table border stripe v-loading={ this.loading } element-loading-text="拼命加载中" data={ this.tableData } on-sort-change={ obj => { this.sortChange(obj) } } style="width: 100%">
  28. {
  29. this.columns.map(columnObj => {
  30. return <el-table-column prop={ columnObj.prop } label={ columnObj.label } sortable={ columnObj.sortable } width={ columnObj.width }
  31. {...{
  32. scopedSlots: {
  33. default: scope => {
  34. return columnObj.hasOwnProperty('render') ? columnObj.render(scope.index, scope.row) : scope.row[columnObj.prop]
  35. }
  36. }
  37. }}
  38. >
  39. </el-table-column>
  40. })
  41. }
  42. </el-table>
  43. )
  44. }
  45. }
  46. </script>
  47. 复制代码

1、使用方法

  1. <common-table :columns="columns" :table-data="tableData" :loading="loading" @sort-change="sortChange"></common-table>
  2. 复制代码

2、columns 配置

  1. {
  2. label: '',
  3. prop: '',
  4. width: '100',
  5. sortable: true
  6. render: ()=>{}
  7. }
  8. 复制代码

自定义配置渲染,传入render函数,如果有render函数,优先使用render函数结果

Github地址:github.com/mrtanweijie…

element-ui 通用表单封装及VUE JSX应用的更多相关文章

  1. vue + element ui 阻止表单输入框回车刷新页面

    问题 在 vue+element ui 中只有一个输入框(el-input)的情况下,回车会提交表单. 解决方案 在 el-form 上加上 @submit.native.prevent 这个则会阻止 ...

  2. vue+element ui 重置表单

    <el-dialog :title="addForm.title" :visible.sync="dialogFormVisible" width=&qu ...

  3. element ui form表单清空规则

    公司项目重构,经过商定使用element ui.在重构项目的时候发现一下element ui上很蛋疼的东西. 例如,这个form表单就是一个.趁着在高铁上没事,把想写的东西写一下. 先说一下eleme ...

  4. element ui FORM表单

    form表单 Form-Item Slot [label] 旧版语法 <el-form-item label="活动名称" prop="name"> ...

  5. 封装Vue Element的form表单组件

    前两天封装了一个基于vue和Element的table表格组件,阅读的人还是很多的,看来大家都是很认同组件化.高复用这种开发模式的,毕竟开发效率高,代码优雅,逼格高嘛.虽然这两天我的心情很糟糕,就像& ...

  6. Vue+Element的动态表单,动态表格(后端发送配置,前端动态生成)

    Vue+Element的动态表单,动态表格(后端发送配置,前端动态生成) 动态表单生成 ElementUI官网引导 Element表单生成 Element动态增减表单,在线代码 关键配置 templa ...

  7. jquery自动将form表单封装成json的具体实现

    前端页面:<span style="font-size:14px;"> <form action="" method="post&q ...

  8. JS通用表单验证函数,基于javascript正则表达式

    表单的验证在实际的开发当中是件很烦琐又无趣的事情今天在做一个小项目的时候,需要JS验证,寻找到一个比较好的东西 地址如下: http://blog.csdn.net/goodfunman/archiv ...

  9. Vue iview 表单封装验证

    以下内容转自iview社区,仅供自己查看使用 Form表单部分 <div> <Form ref="FormOne" :model="FormOne&qu ...

随机推荐

  1. Light of future-冲刺Day 4

    目录 1.SCRUM部分: 每个成员进度 SCRUM 会议的照片 签入记录 代码运行截图 用户浏览界面 管理员浏览界面 2.PM 报告: 时间表 燃尽图 任务总量变化曲线 每名成员的贡献比 归属班级 ...

  2. PTA数据结构与算法题目集(中文) 7-41PAT排名汇总 (25 分)

    PTA数据结构与算法题目集(中文)  7-41PAT排名汇总 (25 分) 7-41 PAT排名汇总 (25 分)   计算机程序设计能力考试(Programming Ability Test,简称P ...

  3. LeetCode | 1013. 将数组分成和相等的三个部分

    给定一个整数数组 A,只有我们可以将其划分为三个和相等的非空部分时才返回 true,否则返回 false. 形式上,如果我们可以找出索引i+1 < j且满足(A[0] + A[1] + ... ...

  4. CF633(div.2)A. Filling Diamonds

    题目描述 http://codeforces.com/contest/1339/problem/A 给定一个 \(n(1\le n \le 10^9)\) ,问用一个由两个三角形组成的菱形,填充下面这 ...

  5. mpvue中使用flyjs全局拦截

    mpvue全局属性设置,在我之前的文章中有介绍,今天想记录的就是怎么和Fly.js结合使用来实现全局拦截功能: 首先我们要安装好Flyio,在mpvue项目中我们用npm下载安装: npm insta ...

  6. 01 微信小程序创建组件和使用组件

    01 创建组件 遇见的困难 图标显示不出来,是因为你没有在组件的css中引入,所以显示不出来. 我一直以为是一个坑.结果是自己没有整清楚 01==>在page的同级目录下,创建一个文件夹,命名为 ...

  7. 初识docker与理解

    因最近公司的一个新项目,有一个业务场景是需要给多个甲方的服务器配置运行环境与部署,所以考虑使用docker来实现环境配置的统一 1.docker是什么 docker是一种容器虚拟化技术的实现,相当于在 ...

  8. Vue 实战项目: 硅谷外卖(1)

    第 1 章: 准备 1.1. 项目描述 1) 此项目为外卖 WebApp(SPA) 2) 包括商家, 商品, 购物车, 用户等多个子模块 3) 使用 Vue 全家桶+ES6+Webpack 等前端最新 ...

  9. 【图机器学习】cs224w Lecture 7 - 节点的表示

    目录 Node Embedding Random Walk node2vec TransE Embedding Entire Graph Anonymous Walk Reference 转自本人:h ...

  10. 29.3 ArrayList、List、LinkedList(链表)优缺点

    ArrayList.List特点:查询快.增删慢 链表特点:查询慢,增删快 案例 package day29_collection集合体系; import java.util.ArrayList; i ...