jsx 使用文档:https://cn.vuejs.org/v2/guide/render-function.html
例子:
<script >
import * as _ from 'lodash'
import { reduce } from '../../util/func.js'
export default {
props: {
showBtn: {
default: true
},
fields: {
type: Array,
required: true
},
values: {
default: null
},
column: {
default: 0
},
inline: {
default: false
},
labelWidth: {
default: '100px'
},
btnText: {
default: '保存'
},
btnIcon: {
default: undefined
},
btnHandler: {
default: null
}
},
data() {
return {
myValues: this.fields.reduce((rs, item) => {
rs[item.dataIndex] = this.values ? this.values[item.dataIndex] : ''
return rs
}, {})
}
},
computed: {
columnSpan() {
let c = this.column || 1
if (this.column == 0 && this.fields.length > 6) {
c = 2
}
return parseInt(24 / c)
},
myGroups() {
let groups = {}
this.fields.forEach((item, index) => {
const {
dataIndex,
component = 'el-input',
header: label,
itemCls = '',
itemStyle = '',
itemOn = {},
itemOpts = {},
fieldCls = '',
fieldStyle = {},
fieldOn = {},
group='其他',
fieldOpts = {}
} = item
itemOpts.label = itemOpts.label || label
itemOpts.prop = itemOpts.prop || dataIndex
// 会覆盖
// itemOpts.class = 'asdfasdf'
fieldOpts.placeholder = fieldOpts.placeholder || label
fieldOn.input = reduce([this.onInput.bind(this, dataIndex), fieldOn.input])
groups[group] = groups[group] || []
groups[group].push({
dataIndex: dataIndex,
dataKey: dataIndex + '-' + index,
component,
opts: {
item: {
attrs: {
...itemOpts
},
class: itemCls,
style: itemStyle,
on: {
...itemOn
}
},
field: {
attrs: {
...fieldOpts
},
class: fieldCls,
style: fieldStyle,
on: {
...fieldOn
}
}
}
})
})
return {
hasLegend: Object.keys(groups).length > 1,
items: Object.keys(groups).map(k => {
return {
group: k,
items: groups[k]
}
})
}
}
},
methods: {
submit() {
this.btnHandler && this.btnHandler(this.myValues)
},
onInput(dataIndex, nv) {
this.myValues[dataIndex] = nv
},
loadData(data) {
data = data || {}
Object.keys(this.myValues).forEach(k => {
this.myValues[k] = data[k] || null
})
},
reset() {
this.loadData()
},
renderItem(item) {
const Comp = item.component || 'el-input'
let its=_.cloneDeep(item.opts.item)
return (
<el-form-item key={item.dataKey} {...its}>
<Comp value={this.myValues[item.dataIndex]} {...item.opts.field} />
</el-form-item>
)
}
},
render(h, ctx) {
let me = this
let child = null
let myGroups=this.myGroups;
if (this.inline) {
child = myGroups.items[0].items.map(item => {
return this.renderItem(item)
})
} else {
child = myGroups.items.map(groupItem => {
return (
<fieldset
class={myGroups.hasLegend ? 'has-legend' : 'no-legend'}
key={groupItem.group}>
{myGroups.hasLegend && <legend>{groupItem.group}</legend>}
{groupItem.items.map(item => {
return (
<el-col span={this.columnSpan} key={item.dataKey}>
{this.renderItem(item)}
</el-col>
)
})}
</fieldset>
)
})
}
return (
<el-form
class="easy-form"
inline={this.inline}
labelWidth={this.labelWidth}
attrs={{ ...this.$attrs, model: this.myValues }}
on={{ ...this.$listeners }}>
<input type="text" style="display:none;" />
<input
type="password"
autocomplete="new-password"
style="display:none;"
/>
{
child
}
{(this.showBtn && (
<el-form-item>
<el-button
icon={this.btnIcon}
onClick={this.submit.bind(this)}
type="primary">
{this.btnText}
</el-button>
</el-form-item>
)) ||
null}
{this.$slots.default}
</el-form>
)
}
}
</script>
<style lang="scss">
.easy-form {
fieldset {
border-width: 0;
&.has-legend {
border-color: #1d0e0e;
border-top-width: 1px;
legend {
// color: #efefef;
font-size: 14px;
}
}
}
}
</style>
使用
<template>
<div id="test">
<div>
<h1>typeScript{{ $locale('test.name') }}</h1>
</div>
<div>
<el-radio-group v-model="column">
<el-radio :label="1">1</el-radio>
<el-radio :label="2">2</el-radio>
<el-radio :label="3">3</el-radio>
<el-radio :label="4">4</el-radio>
</el-radio-group>
</div>
<easy-form class="hello" :column="column" :fields="fields" :rules="rules">
<h4>asdf</h4>
</easy-form>
</div>
</template>
<script>
export default {
components: {
},
data() {
return {
column: 1,
fields: [
{
header: '用户名',
dataIndex: 'userName',
group: 'hello',
itemOn:{
click:()=>{
console.log('click')
}
},
fieldOn:{
focus:()=>{
console.log('click field')
}
},
itemStyle:{
background:'black'
},
fieldStyle:{
color:'green'
},
fieldCls:'test',
},
{
header: '密码',
dataIndex: 'password'
}, {
header: '密码6',
dataIndex: 'password6',
component:'select-category'
},
{
header: '用户名1',
dataIndex: 'userName1',
component: 'date-range'
},
{
header: '密码1',
dataIndex: 'password1',
component: 'upload-file'
},
{
header: '用户名2',
dataIndex: 'userName2',
component: 'upload-img'
},
{
header: '密码2',
dataIndex: 'password2'
},
{
header: '用户名3',
dataIndex: 'userName3',
component: 'el-date-picker'
},
{
header: '密码3',
dataIndex: 'password3',
component: 'enum-select',
fieldOpts: {
enum: 'sex',
type: 'radio'
}
},
{
header: '用户名4',
dataIndex: 'userName4',
component: 'enum-select',
fieldOpts: {
enum: 'vtype'
}
},
{
header: '密码4',
dataIndex: 'password4',
component: 'enum-select',
fieldOpts: {
getData() {
return new Promise(resolve => {
setTimeout(() => {
resolve({
result: {
list: [
{ id: '1', name: 't1' },
{ id: '2', name: 't2' },
{ id: '3', name: 't3' },
{ id: '4', name: 't4' },
{ id: '5', name: 't5' }
]
}
})
}, 1500)
})
}
}
}
],
rules: {
userName: [this.$rules.required(), this.$rules.minLength(2)],
password: [this.$rules.required(), this.$rules.minLength(2)]
},
name: 'name'
}
},
mounted() {
console.log('test')
console.log(document.getElementById('test'))
console.log(document.getElementById('t1'))
console.log(document.getElementById('t2'))
}
}
</script>