fix(v-model): avoid mutation when using Set models + fix multi select Set model update
This commit is contained in:
parent
83a79a829c
commit
f2b0a8e81d
@ -884,18 +884,21 @@ describe('vModel', () => {
|
|||||||
foo.selected = true
|
foo.selected = true
|
||||||
triggerEvent('change', input)
|
triggerEvent('change', input)
|
||||||
await nextTick()
|
await nextTick()
|
||||||
|
expect(data.value).toBeInstanceOf(Set)
|
||||||
expect(data.value).toMatchObject(new Set(['foo']))
|
expect(data.value).toMatchObject(new Set(['foo']))
|
||||||
|
|
||||||
foo.selected = false
|
foo.selected = false
|
||||||
bar.selected = true
|
bar.selected = true
|
||||||
triggerEvent('change', input)
|
triggerEvent('change', input)
|
||||||
await nextTick()
|
await nextTick()
|
||||||
|
expect(data.value).toBeInstanceOf(Set)
|
||||||
expect(data.value).toMatchObject(new Set(['bar']))
|
expect(data.value).toMatchObject(new Set(['bar']))
|
||||||
|
|
||||||
foo.selected = true
|
foo.selected = true
|
||||||
bar.selected = true
|
bar.selected = true
|
||||||
triggerEvent('change', input)
|
triggerEvent('change', input)
|
||||||
await nextTick()
|
await nextTick()
|
||||||
|
expect(data.value).toBeInstanceOf(Set)
|
||||||
expect(data.value).toMatchObject(new Set(['foo', 'bar']))
|
expect(data.value).toMatchObject(new Set(['foo', 'bar']))
|
||||||
|
|
||||||
foo.selected = false
|
foo.selected = false
|
||||||
|
@ -118,11 +118,13 @@ export const vModelCheckbox: ModelDirective<HTMLInputElement> = {
|
|||||||
assign(filtered)
|
assign(filtered)
|
||||||
}
|
}
|
||||||
} else if (isSet(modelValue)) {
|
} else if (isSet(modelValue)) {
|
||||||
|
const cloned = new Set(modelValue)
|
||||||
if (checked) {
|
if (checked) {
|
||||||
modelValue.add(elementValue)
|
cloned.add(elementValue)
|
||||||
} else {
|
} else {
|
||||||
modelValue.delete(elementValue)
|
cloned.delete(elementValue)
|
||||||
}
|
}
|
||||||
|
assign(cloned)
|
||||||
} else {
|
} else {
|
||||||
assign(getCheckboxValue(el, checked))
|
assign(getCheckboxValue(el, checked))
|
||||||
}
|
}
|
||||||
@ -168,7 +170,8 @@ export const vModelRadio: ModelDirective<HTMLInputElement> = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const vModelSelect: ModelDirective<HTMLSelectElement> = {
|
export const vModelSelect: ModelDirective<HTMLSelectElement> = {
|
||||||
created(el, { modifiers: { number } }, vnode) {
|
created(el, { value, modifiers: { number } }, vnode) {
|
||||||
|
const isSetModel = isSet(value)
|
||||||
addEventListener(el, 'change', () => {
|
addEventListener(el, 'change', () => {
|
||||||
const selectedVal = Array.prototype.filter
|
const selectedVal = Array.prototype.filter
|
||||||
.call(el.options, (o: HTMLOptionElement) => o.selected)
|
.call(el.options, (o: HTMLOptionElement) => o.selected)
|
||||||
@ -176,7 +179,13 @@ export const vModelSelect: ModelDirective<HTMLSelectElement> = {
|
|||||||
(o: HTMLOptionElement) =>
|
(o: HTMLOptionElement) =>
|
||||||
number ? toNumber(getValue(o)) : getValue(o)
|
number ? toNumber(getValue(o)) : getValue(o)
|
||||||
)
|
)
|
||||||
el._assign(el.multiple ? selectedVal : selectedVal[0])
|
el._assign(
|
||||||
|
el.multiple
|
||||||
|
? isSetModel
|
||||||
|
? new Set(selectedVal)
|
||||||
|
: selectedVal
|
||||||
|
: selectedVal[0]
|
||||||
|
)
|
||||||
})
|
})
|
||||||
el._assign = getModelAssigner(vnode)
|
el._assign = getModelAssigner(vnode)
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user