Ant Design Vue中动态增减表单项
按钮【增加】弹出的界面中动态的添加删除输入框,输入内容后保存为数组值(可以拼接为字符串保存),【编辑】显示时传入数组,若是字符串,可以通过转化为数组
效果图(增加页面、编辑页面)
代码:
<template>
<div>
<div class="student-modal-container" >
<a-form :form="form" :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol">
<a-row>
<a-col :span="12" >
<a-form-item label="消息1:">
<a-select :disabled="type === 'view'" v-decorator="['category', {rules: validateRules.category, initialValue: formData.category}]" placeholder="请选择">
<a-select-option
v-for="item in options"
:key="item.value"
:value="item.value"
>
{{ item.label }}
</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="消息2:">
<a-select :disabled="type === 'view'" v-decorator="['messCategory', {rules: validateRules.messCategory, initialValue: formData.messCategory}]" placeholder="请选择">
<a-select-option
v-for="item in messOptions"
:key="item.value"
:value="item.value"
>
{{ item.label }}
</a-select-option>
</a-select>
</a-form-item>
</a-col>
</a-row>
<a-row v-for="item in keysList" :key="item">
<a-col :span="12">
<a-form-item label="内容" >
<a-input
placeholder="请输入内容"
v-decorator="[
`${title}arr[${item}]`,
{
initialValue: arr[item] ? arr[item] : undefined,
rules: [{ required: true, message: '请输入内容' }]
}
]"
style="width: 60%; margin-right: 8px"/>
<template v-if="keysList.length > 1">
<a-icon
type="minus-circle"
class="dynamic-delete-button"
@click="removeRow(item)" />
<!-- </a-button>-->
</template>
</a-form-item>
</a-col>
</a-row>
<a-row>
<a-col :span="12">
<a-form-item v-bind="formItemLayoutWithOutLabel">
<a-button type="dashed" style="width: 60%" @click="addRow">
<a-icon type="plus-circle" />
</a-button>
</a-form-item>
</a-col >
</a-row>
</a-form>
</div>
</div>
</template>
script中的methods
<script>
let id = 0;
import { Select, Form, Input, Row, Col ,Button ,Icon } from 'ant-design-vue';
const ASelectOption = Select.Option;
const AFormItem = Form.Item;
const PARTONE = 'partOne';
export default {
name: "EditForm",
components: {
ASelect: Select, ASelectOption, AForm: Form, AFormItem,
AInput: Input, ARow: Row, ACol: Col,ATextarea: Input.TextArea,
AButton: Button,
AIcon: Icon,
},
data: function() {
return {
id: 0,
keysList: [],
validateRules: {
category: [{required: this.type !== 'view', message: '消息不能为空'}],
names: [{required: this.type !== 'view', message: '内容不能为空'}],
messCategory: [{required: this.type !== 'view', message: '消息不能为空'}],
},
options: [
{ value: '33', label: '33' }
],
messOptions: [
{ value: '22', label: '22' }
],
// 数据
data: Object.assign({}, this.formData),
formItemLayout: {
labelCol: {
xs: { span: 24 },
sm: { span: 4 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 20 },
},
},
formItemLayoutWithOutLabel: {
wrapperCol: {
xs: { span: 24, offset: 0 },
sm: { span: 20, offset: 4 },
},
},
form: this.$form.createForm(this),
arr: [],
}
},
created () {
// this.form = this.$form.createForm(this)
this.form = this.$form.createForm(this, { name: 'StudentEditForm' });//StudentEditForm
this.init();
},
props: {
formData: {
type: Object,
default: () => {return {}}
},
type: {
type: String,
default: 'create'
},
title: {
type: String,
default: ''
},
wrapHeight: { // 表单容器的高度
type: Number,
default: 120
},
// arr: {
// type: Array,
// default: function () {
// return []
// }
// }
},
methods: {
handleCancel() {
this.$emit('on-cancel')
},
handleConfirm(type) {
this.$emit('on-confirm', type, this.data);
},
init () {
const arr = []
if (this.formData.arr !== undefined){
this.arr = this.formData.arr
}
if (this.arr.length !== 0) {
for (let i = 0; i < (this.formData.arr).length-1; i++) {
arr.push(i)
this.id = this.id + 1
}
}
else{
arr.push(0)
this.id = this.id + 1
}
this.keysList = arr
},
// 移除某行
removeRow (k) {
if (this.keysList.length === 1) { // 如果存在可以移除所有行的情况,把条件改为this.keysList.length === 0即可
return
}
this.keysList = this.keysList.filter(item => item !== k)
},
// 新增一行
addRow () {
this.id = this.id + 1
this.keysList = this.keysList.concat(this.id)
},
}
}
</script>
样式
```html
<style lang="less" scoped>
.student-modal-container{
.ant-form{
.ant-input-disabled, .ant-select-disabled {
background: none;
border: none;
color: rgba(0,0,0,.65);
font-weight: 700;
cursor: auto;
/deep/ .ant-select-selection{
background: none;
border: none;
cursor: auto;
.ant-select-arrow{
display: none;
}
}
}
}
.dynamic-delete-button {
cursor: pointer;
position: relative;
top: 4px;
font-size: 24px;
color: #999;
transition: all 0.3s;
}
.dynamic-delete-button:hover {
color: #777;
}
.dynamic-delete-button[disabled] {
cursor: not-allowed;
opacity: 0.5;
}
}
.dynamic-wrap {
padding-top: 10px;
background-color: white;
overflow-y: scroll;
overflow-x: hidden;
&::-webkit-scrollbar {
width: 7px;
}
&::-webkit-scrollbar-thumb {
background: #d8d8d8;
border-radius: 10px;
}
&::-webkit-scrollbar-track-piece {
background: transparent;
}
}
.minusRowBtn {
color: #f5222d;
background: #fff1f0;
border-color: #ffa39e;
padding-right: 7px;
padding-left: 7px;
height: 29px;
margin-left: 10px;
}
.addRowBtn {
width: 70%;
color: #1890ff;
border-color: #91d5ff;
margin: 0px 0px 20px 70px;
}
</style>