fix(components): [form] on post rules update reset field (#19129)

* fix(components): [form] track rules on post update

closed #19109

* fix(components): [form] ensure reset field state if no rules

closed #19128

* test: add validate on rule change case

* chore: on rules update reset field error

* chore: fixup

---------

Co-authored-by: btea <2356281422@qq.com>
This commit is contained in:
Noblet Ouways
2025-01-06 15:58:08 +01:00
committed by GitHub
parent eab540a3f7
commit 536548e753
2 changed files with 43 additions and 2 deletions

View File

@@ -1,5 +1,5 @@
// @ts-nocheck
import { nextTick, reactive, ref } from 'vue'
import { computed, nextTick, reactive, ref } from 'vue'
import { mount } from '@vue/test-utils'
import {
afterEach,
@@ -16,6 +16,7 @@ import {
ElCheckbox as Checkbox,
ElCheckboxGroup as CheckboxGroup,
} from '@element-plus/components/checkbox'
import Button from '@element-plus/components/button/src/button.vue'
import Input from '@element-plus/components/input'
import Form from '../src/form.vue'
import FormItem from '../src/form-item.vue'
@@ -643,6 +644,45 @@ describe('Form', () => {
expect(fn.mock.calls[1][0]).toBe('finally')
})
it('validate on rule change', async () => {
const form = reactive({
email: '',
})
const value = ref(0)
const rules = computed(() => ({
age: [
{
required: true,
message: `age is: ${value.value}`,
trigger: 'blur',
},
],
}))
const wrapper = mount({
setup() {
return () => (
<Form ref="form" model={form} rules={rules}>
<FormItem ref="age" prop="age" label="age">
<Input v-model={form.age} />
<Button onClick={() => value.value++}>increase</Button>
</FormItem>
</Form>
)
},
})
vi.useFakeTimers()
await wrapper.findComponent(Button).trigger('click')
vi.runAllTimers()
vi.useRealTimers()
await nextTick()
expect(value.value).toBe(1)
expect(rules.value.age[0].message).toBe('age is: 1')
expect(wrapper.find('.el-form-item__error').text()).toBe('age is: 1')
})
describe('FormItem', () => {
const onSuccess = vi.fn()
const onError = vi.fn()

View File

@@ -109,6 +109,7 @@ const doValidateField = async (
for (const field of fields) {
try {
await field.validate('')
if (field.validateState === 'error') field.resetField()
} catch (fields) {
validationErrors = {
...validationErrors,
@@ -160,7 +161,7 @@ watch(
validate().catch((err) => debugWarn(err))
}
},
{ deep: true }
{ deep: true, flush: 'post' }
)
provide(