fix(components): [checkbox-group] dynamic prop-value cause ivalidate loop (#21309)

* fix(components): [checkbox-group]

fix  el-checkbox-group in el-form-item with dynamic prop cause infinite update loop

closed #21305

* chore: fix lint

---------

Co-authored-by: Dsaquel <291874700n@gmail.com>
This commit is contained in:
Shaobo Lua
2025-07-15 00:06:21 +08:00
committed by GitHub
parent a5582a78f3
commit db680e4dd0
2 changed files with 42 additions and 5 deletions

View File

@@ -1,7 +1,7 @@
import { nextTick, ref } from 'vue'
import { nextTick, reactive, ref } from 'vue'
import { mount } from '@vue/test-utils'
import { describe, expect, test } from 'vitest'
import { ElFormItem } from '@element-plus/components/form'
import { ElForm, ElFormItem } from '@element-plus/components/form'
import Checkbox from '../src/checkbox.vue'
import CheckboxButton from '../src/checkbox-button.vue'
import CheckboxGroup from '../src/checkbox-group.vue'
@@ -162,6 +162,43 @@ describe('Checkbox', () => {
expect(checkList.value).toContain('b')
})
test('checkbox group with dynamic modelValue', async () => {
const form = reactive<{ checked: string }>({ checked: '' })
const wrapper = mount({
setup() {
return () => (
<ElForm model={form}>
<ElFormItem
prop="check"
rules={[
{ required: true, message: 'Must has one check box checked' },
]}
>
<CheckboxGroup
modelValue={form.checked.split(',')}
onUpdate:modelValue={(val) => {
form.checked = val.filter(Boolean).join(',')
}}
>
<Checkbox label="a" value="a" ref="a"></Checkbox>
<Checkbox label="b" value="b" ref="b"></Checkbox>
</CheckboxGroup>
</ElFormItem>
</ElForm>
)
},
})
const checkboxA = wrapper.findComponent({ ref: 'a' })
await checkboxA.trigger('click')
expect(form.checked).toBe('a')
const checkboxB = wrapper.findComponent({ ref: 'b' })
await checkboxB.trigger('click')
expect(form.checked).toBe('a,b')
form.checked = ''
await nextTick()
expect(checkboxA.classes()).not.toContain('is-checked')
expect(checkboxB.classes()).not.toContain('is-checked')
})
test('checkbox group without modelValue', async () => {
const checkList = ref([])
const wrapper = mount({

View File

@@ -15,7 +15,7 @@
<script lang="ts" setup>
import { computed, nextTick, provide, toRefs, watch } from 'vue'
import { pick } from 'lodash-unified'
import { isEqual, pick } from 'lodash-unified'
import { CHANGE_EVENT, UPDATE_MODEL_EVENT } from '@element-plus/constants'
import { debugWarn } from '@element-plus/utils'
import { useNamespace } from '@element-plus/hooks'
@@ -69,8 +69,8 @@ provide(checkboxGroupContextKey, {
watch(
() => props.modelValue,
() => {
if (props.validateEvent) {
(newVal, oldValue) => {
if (props.validateEvent && !isEqual(newVal, oldValue)) {
formItem?.validate('change').catch((err) => debugWarn(err))
}
}