通常在作後臺OA的時候會發現表單重複代碼比較多,且邏輯基本同樣,每次新加一個表單都須要拷貝基本一致的代碼結構,而後只是簡單地修改對應的字段進行開發html
提取重複的表單邏輯造成通用的組件,經過約定的JSON數據結構配置生成表單vue
一、使用方法git
<common-form :form-option="formOption" :is-reset-form-flag="isResetFormFlag"></common-form>
複製代碼
接收的props:github
isResetFormFlag:是否更新表單內容標誌,用於觸發更新表單的formModelbash
formOption:表單配置,下有詳細配置說明babel
isDisabled:表單是否可編輯數據結構
二、單一表單組配置異步
{
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
}]
}
複製代碼
三、多表單組配置ide
formOption: {
name: 'channel-form',
data: {},
groups: [{
title: '',// 組標題
tips: ''// 組提示
items: [] // 組表單項,和單一組配置一致
}]
}
複製代碼
根據配置輸出不一樣的form-item,須要特殊處理的表單項經過jsx
由使用的地方自定義實現函數
什麼是JSX:cn.vuejs.org/v2/guide/re…
使用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 | 否 | 會在回調函數包含表單的數據及表單引用 |
v-model支持: babel-plugin-jsx-v-model
sync 修飾符寫法
visible={ this.dialogImgVisible } {...{on: {'update:visible': (val) => { this.dialogImgVisible = val }}}}
複製代碼
一、生成列表
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
}
複製代碼
二、生成下拉菜單
generateSelect (item) {
return <el-select v-model={ this.formModel[item.name] } style={ item.style || this.defaultStyle }>{ this.generateList(item) }</el-select>
}
複製代碼
備註:其餘項實現相似
三、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>
複製代碼
一、使用方法
<common-table :columns="columns" :table-data="tableData" :loading="loading" @sort-change="sortChange"></common-table>
複製代碼
二、columns 配置
{
label: '',
prop: '',
width: '100',
sortable: true
render: ()=>{}
}
複製代碼
自定義配置渲染,傳入render函數,若是有render函數,優先使用render函數結果
Github地址:github.com/mrtanweijie…