element-ui 通用表单封装及VUE JSX应用

vue

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

一般在做后台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表单组Arraygroups 和 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应用 的全部内容, 来源链接: utcz.com/z/380382.html

回到顶部