根据项目要求要动态添加表单并能传给后台,我采用的是ant design的 FormModel 表单,动态增减表单项(在最后一个例子),如下图:
下面是我的实现图,主要功能有:
添加报表项(类型是 inputString,select),添加日期 类型是 date,添加地区 类型是 area,
删除报表项,添加报表项的子表单项,删除报表项的子表单项,上下移动整个报表项,输入报表项值
看似简单的个动态添加表单项,实则工作量很大,下面上代码:
<a-form-item
v-for="(k,index) in reportItems"
:key="index"
:required="false"
>
<a-input
@keyup="changeReportItemLabel(k.key)"
v-decorator="[
`names[${k.key}]`,
{
validateTrigger: ['keyup', 'blur'],
initialValue:k.lable,
rules: [
{
required: true,
whitespace: true,
message: '请输入名称',
},
],
},
]"
placeholder="请输入名称"
style="width: 25%;
border: none;
border-bottom: 1px solid;
border-radius: 0;"
/>
<span style="margin:0 3px;">:</span>
<a-input
style="width: 60%; margin-right: 8px"
:disabled="true"
/>
<a-icon
v-if="reportItems[index].type=='inputString'"
type="plus-circle"
theme="twoTone"
twoToneColor="#52c41a"
class="dynamic-delete-button"
@click="addOne(index)"
/>
<a-icon
theme="twoTone"
twoToneColor="red"
type="minus-circle-o"
class="dynamic-delete-button"
@click="remove(index)"
/>
<a-icon
type="arrow-up"
class="arrow"
v-show="index == 0?false:true"
@click="upFieldOrder(index)"
/>
<a-icon
type="arrow-down"
class="arrow"
v-show="index == reportItems.length - 1?false:true"
:disabled="true"
@click="downFieldOrder(index)"
/>
<!--================================================================= -->
<div
style="margin-left: 25%"
>
<br>
<a-form-item
v-for="(item,idx) in k.options"
:key="item.key"
:required="false"
>
<span style="margin:0 3px;">:</span>
<a-input
@keyup="ItemValue(k.key, item.key)"
v-decorator="[
`names[${k.key}]_options[${item.key}]`,
{
validateTrigger: ['keyup', 'blur'],
initialValue:item.val,
rules: [
{
required: true,
whitespace: true,
message: '请输入值',
}
]
}
]"
style="width: 80%; margin-right: 8px"
/>
<a-icon
class="dynamic-delete-button"
type="minus-circle-o"
@click="removeOne(index,idx)"
/>
</a-form-item>
</div>
</a-form-item>
</a-row>
<a-row
style="display: flex;justify-content: space-between;"
>
<a-form-item>
<a-button
type="dashed"
style="width: 250px"
@click="add('inputString')"
>
<a-icon type="plus" /> 添加报表项
</a-button>
</a-form-item>
<a-form-item>
<a-button
type="dashed"
style="width: 250px"
@click="add('date')"
>
<a-icon type="plus" />日期
</a-button>
</a-form-item>
<a-form-item>
<!-- :disabled="reportItems.filter(e=>e.type=='area').length>=1?true:false" -->
<a-button
type="dashed"
style="width: 250px"
@click="add('area')"
>
<a-icon type="plus" />地区
</a-button>
</a-form-item>
export default {
data () {
return {
diable: false,
reportItems: [],//报告结构
form: this.$form.createForm(this),
}
},
methods: {
//=============================动态构建报告项 begin================================
changeReportItemLabel (k) {
let lable = this.form.getFieldValue(`names[${k}]`)
this.reportItems.filter(e => e.key == k)[0].lable = lable
},
/**
* 删除一整个报表项
*/
remove (k) {
this.reportItems.splice(k, 1)
},
/**
* 添加一整个报表项
*/
add (type) {
this.reportItems.push({ key: this.reportItems.length, type: type, options: [] })
},
/**
* 移除一个报表项的子表单项
*/
removeOne (k, k2) {
this.reportItems[k].options.splice(k2, 1)
},
/**
* 添加一个报表项的子表单项
*/
addOne (oneIndex) {
let reportItem = this.reportItems[oneIndex]
let lastItem = reportItem.options[reportItem.options.length - 1]
let key2 = lastItem ? lastItem.key + 1 : 0
this.reportItems[oneIndex].options.push({ key: key2 })
},
/**
* 报表项的子表单项---输入值并传给后台
*/
ItemValue (key1, key2) {
let value = this.form.getFieldValue(`names[${key1}]_options[${key2}]`)
this.reportItems[key1].options[key2].val = value
},
/**
* 上移
*/
upFieldOrder (index) {
let temp = this.reportItems[index - 1]
Vue.set(this.reportItems, index - 1, this.reportItems[index])
Vue.set(this.reportItems, index, temp)
console.log('reportItems---------', this.reportItems)
},
/**
* 下移
*/
downFieldOrder (index) {
let down = this.reportItems[index + 1]
Vue.set(this.reportItems, index + 1, this.reportItems[index])
Vue.set(this.reportItems, index, down)
console.log('reportItems---------', this.reportItems)
},
//=============================动态 end==================================
onSave () {
this.form.validateFields((err, fieldsValue) => {
let { code, title } = fieldsValue
// 在此处判断element.options的类型是什么,默认是inputString,有子表单项时是select
this.reportItems.forEach(element => {
if (element.options.length > 0) {
element.type = 'select'
}
})
if (!err) {
this.conditions.content = JSON.stringify(this.reportItems)
projectItemsAdd(this.conditions).then(res => {
this.onClose()
this.$parent.getCategory()
})
}
})
}
}
}
全是个人写项目所得,有什么不懂得可以欢迎评论提问