vuecssuiant-designantdreactantantd-vueenterprisefrontendui-designvue-antdvue-antd-uivue3vuecomponent
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
132 lines
2.9 KiB
132 lines
2.9 KiB
<docs> |
|
--- |
|
order: 3 |
|
title: |
|
zh-CN: 动态增减表单项 |
|
en-US: Dynamic Form Item |
|
--- |
|
|
|
## zh-CN |
|
|
|
动态增加、减少表单项。 |
|
|
|
## en-US |
|
|
|
Add or remove form items dynamically. |
|
</docs> |
|
<template> |
|
<a-form |
|
ref="formRef" |
|
name="dynamic_form_item" |
|
:model="dynamicValidateForm" |
|
v-bind="formItemLayoutWithOutLabel" |
|
> |
|
<a-form-item |
|
v-for="(domain, index) in dynamicValidateForm.domains" |
|
:key="domain.key" |
|
v-bind="index === 0 ? formItemLayout : {}" |
|
:label="index === 0 ? 'Domains' : ''" |
|
:name="['domains', index, 'value']" |
|
:rules="{ |
|
required: true, |
|
message: 'domain can not be null', |
|
trigger: 'change', |
|
}" |
|
> |
|
<a-input |
|
v-model:value="domain.value" |
|
placeholder="please input domain" |
|
style="width: 60%; margin-right: 8px" |
|
/> |
|
<MinusCircleOutlined |
|
v-if="dynamicValidateForm.domains.length > 1" |
|
class="dynamic-delete-button" |
|
@click="removeDomain(domain)" |
|
/> |
|
</a-form-item> |
|
<a-form-item v-bind="formItemLayoutWithOutLabel"> |
|
<a-button type="dashed" style="width: 60%" @click="addDomain"> |
|
<PlusOutlined /> |
|
Add field |
|
</a-button> |
|
</a-form-item> |
|
<a-form-item v-bind="formItemLayoutWithOutLabel"> |
|
<a-button type="primary" html-type="submit" @click="submitForm">Submit</a-button> |
|
<a-button style="margin-left: 10px" @click="resetForm">Reset</a-button> |
|
</a-form-item> |
|
</a-form> |
|
</template> |
|
|
|
<script lang="ts" setup> |
|
import { reactive, ref } from 'vue'; |
|
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons-vue'; |
|
import type { FormInstance } from 'ant-design-vue'; |
|
|
|
interface Domain { |
|
value: string; |
|
key: number; |
|
} |
|
const formRef = ref<FormInstance>(); |
|
const formItemLayout = { |
|
labelCol: { |
|
xs: { span: 24 }, |
|
sm: { span: 4 }, |
|
}, |
|
wrapperCol: { |
|
xs: { span: 24 }, |
|
sm: { span: 20 }, |
|
}, |
|
}; |
|
const formItemLayoutWithOutLabel = { |
|
wrapperCol: { |
|
xs: { span: 24, offset: 0 }, |
|
sm: { span: 20, offset: 4 }, |
|
}, |
|
}; |
|
const dynamicValidateForm = reactive<{ domains: Domain[] }>({ |
|
domains: [], |
|
}); |
|
const submitForm = () => { |
|
formRef.value |
|
.validate() |
|
.then(() => { |
|
console.log('values', dynamicValidateForm.domains); |
|
}) |
|
.catch(error => { |
|
console.log('error', error); |
|
}); |
|
}; |
|
const resetForm = () => { |
|
formRef.value.resetFields(); |
|
}; |
|
const removeDomain = (item: Domain) => { |
|
const index = dynamicValidateForm.domains.indexOf(item); |
|
if (index !== -1) { |
|
dynamicValidateForm.domains.splice(index, 1); |
|
} |
|
}; |
|
const addDomain = () => { |
|
dynamicValidateForm.domains.push({ |
|
value: '', |
|
key: Date.now(), |
|
}); |
|
}; |
|
</script> |
|
|
|
<style scoped> |
|
.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; |
|
} |
|
</style>
|
|
|