🌐 AI搜索 & 代理 主页
Skip to content

Commit e76d408

Browse files
authored
fix(b-form-checkbox-group): only emit input when value loosely changes (#5432)
* fix(b-form-checkbox-group, b-form-radio-group): only emit `input` when value loosely changes * Update loose-equal.js * Update form-checkbox-group.spec.js
1 parent a4dbf7f commit e76d408

File tree

3 files changed

+56
-7
lines changed

3 files changed

+56
-7
lines changed

src/components/form-checkbox/form-checkbox-group.spec.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,54 @@ describe('form-checkbox-group', () => {
363363
wrapper.destroy()
364364
})
365365

366+
it('does not emit "input" event when value loosely changes', async () => {
367+
const value = ['one', 'two', 'three']
368+
const wrapper = mount(BFormCheckboxGroup, {
369+
attachTo: createContainer(),
370+
propsData: {
371+
options: value.slice(),
372+
checked: value.slice()
373+
}
374+
})
375+
expect(wrapper.classes()).toBeDefined()
376+
const checks = wrapper.findAll('input')
377+
expect(checks.length).toBe(3)
378+
expect(wrapper.vm.localChecked).toEqual(value)
379+
expect(checks.wrappers.every(c => c.find('input[type=checkbox]').exists())).toBe(true)
380+
expect(checks.at(0).element.checked).toBe(true)
381+
expect(checks.at(1).element.checked).toBe(true)
382+
expect(checks.at(2).element.checked).toBe(true)
383+
384+
expect(wrapper.emitted('input')).not.toBeDefined()
385+
386+
// Set internal value to new array reference
387+
wrapper.vm.localChecked = value.slice()
388+
await waitNT(wrapper.vm)
389+
390+
expect(wrapper.vm.localChecked).toEqual(value)
391+
expect(checks.wrappers.every(c => c.find('input[type=checkbox]').exists())).toBe(true)
392+
expect(checks.at(0).element.checked).toBe(true)
393+
expect(checks.at(1).element.checked).toBe(true)
394+
expect(checks.at(2).element.checked).toBe(true)
395+
396+
expect(wrapper.emitted('input')).not.toBeDefined()
397+
398+
// Set internal value to new array (reversed order)
399+
wrapper.vm.localChecked = value.slice().reverse()
400+
await waitNT(wrapper.vm)
401+
402+
expect(wrapper.vm.localChecked).toEqual(value.slice().reverse())
403+
expect(checks.wrappers.every(c => c.find('input[type=checkbox]').exists())).toBe(true)
404+
expect(checks.at(0).element.checked).toBe(true)
405+
expect(checks.at(1).element.checked).toBe(true)
406+
expect(checks.at(2).element.checked).toBe(true)
407+
expect(wrapper.emitted('input')).toBeDefined()
408+
expect(wrapper.emitted('input').length).toBe(1)
409+
expect(wrapper.emitted('input')[0][0]).toEqual(value.slice().reverse())
410+
411+
wrapper.destroy()
412+
})
413+
366414
it('checkboxes reflect group checked v-model', async () => {
367415
const wrapper = mount(BFormCheckboxGroup, {
368416
attachTo: createContainer(),

src/mixins/form-radio-check-group.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { htmlOrText } from '../utils/html'
2+
import looseEqual from '../utils/loose-equal'
23
import normalizeSlotMixin from './normalize-slot'
34
import { BFormCheckbox } from '../components/form-checkbox/form-checkbox'
45
import { BFormRadio } from '../components/form-radio/form-radio'
@@ -70,8 +71,10 @@ export default {
7071
checked(newVal) {
7172
this.localChecked = newVal
7273
},
73-
localChecked(newVal) {
74-
this.$emit('input', newVal)
74+
localChecked(newVal, oldVal) {
75+
if (!looseEqual(newVal, oldVal)) {
76+
this.$emit('input', newVal)
77+
}
7578
}
7679
},
7780
render(h) {

src/utils/loose-equal.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { keys } from './object'
1+
import { hasOwnProperty, keys } from './object'
22
import { isArray, isDate, isObject } from './inspect'
33

44
// Assumes both a and b are arrays!
@@ -46,10 +46,8 @@ const looseEqual = (a, b) => {
4646
return false
4747
}
4848
for (const key in a) {
49-
// eslint-disable-next-line no-prototype-builtins
50-
const aHasKey = a.hasOwnProperty(key)
51-
// eslint-disable-next-line no-prototype-builtins
52-
const bHasKey = b.hasOwnProperty(key)
49+
const aHasKey = hasOwnProperty(a, key)
50+
const bHasKey = hasOwnProperty(b, key)
5351
if ((aHasKey && !bHasKey) || (!aHasKey && bHasKey) || !looseEqual(a[key], b[key])) {
5452
return false
5553
}

0 commit comments

Comments
 (0)