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

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

二、预期结果

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

1、使用方法

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

接收的props:

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

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

isDisabled:表单是否可编辑

2、单一表单组配置

{
name: 'channel-form',
data: {},
items: [
{
label: '类型',
name: 'biz_type',
type: 'select',
dataList: [{
index: 1,
text: '业务部'
}]
}
],
rules: {
name: [{ required: true, message: '请输入产品名称', trigger: 'blur' }]
},
btnList: [{
text: '保存',
type: 'primary',
onClick: this.commitForm
}]
}
复制代码

3、多表单组配置

formOption: {
name: 'channel-form',
data: {},
groups: [{
title: '',// 组标题
tips: ''// 组提示
items: [] // 组表单项,和单一组配置一致
}]
}
复制代码

三、实现逻辑

根据配置输出不同的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 修饰符写法

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

七、部分实现代码

1、生成列表

generateList (itemObj) {
let itemEle = []
for (let index = 0; index < itemObj.dataList.length; index++) {
const item = itemObj.dataList[index]
switch (itemObj.type) {
// 下拉菜单
case 'select':
itemEle.push(<el-option key={ item.index } label={ item.text } value={ item.index }></el-option>)
break
// 多选框
case 'checkbox':
itemEle.push(<el-checkbox label={ item.index }>{ item.text }</el-checkbox>)
break
// 单选框
case 'radio':
itemEle.push(<el-radio label={ item.index }>{ item.text }</el-radio>)
break
}
}
return itemEle
}
复制代码

2、生成下拉菜单

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

备注:其他项实现类似

3、render函数

render (h) {
let ele = []
// 表单内容
if (this.isGroup) {
ele = this.generateGroup()
} else {
ele = this.generateFormItems(this.formOption.items)
}
// 按钮列表
let btnListEle = []
this.formOption.btnList.forEach((btn) => {
btnListEle.push(<el-button type={ btn.type } on-click={ () => { btn.onClick(this.$refs[this.formName], this.formModel) } }>{ btn.text }</el-button>)
})
return (
<div class="oa-form-container">
<el-form ref={ this.formName } model={ this.formModel } rules={ this.formOption.rules } inline={ this.inline } disabled={ this.isDisabled } label-width={ this.formOption.labelWidth || '150px'}>
{ ele }
<el-form-item label-width={ this.isGroup ? '0' : '150px'}>{ btnListEle }</el-form-item>
</el-form>
</div>
)
}
复制代码

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

<script>
export default {
props: {
// 表格列
columns: {
type: Array,
default: _ => { return [] }
},
// 表格数据
tableData: {
type: Array,
default: _ => { return [] }
},
// loading 标志
loading: {
type: Boolean,
default: false
}
},
methods: {
sortChange (obj) {
this.$emit('sortChange', obj)
}
},
render () {
return (
<el-table border stripe v-loading={ this.loading } element-loading-text="拼命加载中" data={ this.tableData } on-sort-change={ obj => { this.sortChange(obj) } } style="width: 100%">
{
this.columns.map(columnObj => {
return <el-table-column prop={ columnObj.prop } label={ columnObj.label } sortable={ columnObj.sortable } width={ columnObj.width }
{...{
scopedSlots: {
default: scope => {
return columnObj.hasOwnProperty('render') ? columnObj.render(scope.index, scope.row) : scope.row[columnObj.prop]
}
}
}}
>
</el-table-column>
})
}
</el-table>
)
}
}
</script>
复制代码

1、使用方法

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

2、columns 配置

{
label: '',
prop: '',
width: '100',
sortable: true
render: ()=>{}
}
复制代码

自定义配置渲染,传入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. (C++ Error: Incompatible types in assignment of ‘char*’ to ‘char [2])

    in C++, cannot assign a pointer to an array. c++中char*与char[]不是一种类型,但是在C里面可以,所以尽量使用C++中的类,如string, v ...

  2. Java8 学习笔记--函数式接口与lambda表达式的关系

    在java中,lambda表达式与函数式接口是不可分割的,都是结合起来使用的. 对于函数式接口,我们可以理解为只有一个抽象方法的接口,除此之外它和别的接口相比并没有什么特殊的地方.为了确保函数式接口的 ...

  3. GlusterFS 4.1 版本选择和部署

    GlusterFS 4.1 版本选择和部署 目录 GlusterFS 4.1 版本选择和部署 1 前言相关 1.1 glusterfs优势 1.2 版本选择 1.3 volume知识 2 服务部署 2 ...

  4. CSS 布局水平 & 垂直对齐

    元素居中对齐 margin: auto; 文本居中对齐 text-align: center; 图片居中对齐 要让图片居中对齐, 可以使用 margin: auto; 并将它放到 块 元素中 左右对齐 ...

  5. 记一次Windows蓝屏分析

    大半夜收到此类信息,应该是让所有系统管理员最头大的事情了 首先我快速通过iDRAC,发现服务器发生了重启操作,并得到相关日志信息 通过Dell的官方解释,确定了该问题是OS层面的异常导致.打开Wind ...

  6. vue 全局自定义组件

    1.vue文件 <template> <div style="position: absolute;bottom: 10px;text-align: center;widt ...

  7. 最长回文子窜O(N)

    字符窜同构的性质:同构字符窜拥有最小和最大的表示方法: 最长回文子窜: 1.首先暴力法:(n三方) 枚举每个起点和终点,然后单向扫描判断是不是回文子窜: 2.中心扩散法,(N方) 枚举每个中点,向外扩 ...

  8. Jquery+php鼠标滚动到页面底部自动加载更多内容,使用分页

    1.index.php <style type="text/css"> #container{margin:10px auto;width: 660px; border ...

  9. python从零开始基础入门——开发环境搭建:Visual Studio Code

    前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:山海皆可平z PS:如有需要Python学习资料的小伙伴可以加点击下方 ...

  10. Linux下nginx自启动配置

    1.在linux系统的/etc/init.d/目录下创建nginx文件 vim /etc/init.d/nginx 在脚本中添加一下命令(内容主要参考官方文档) #!/bin/sh # # nginx ...