From: daiwei Date: Sat, 12 Oct 2024 06:56:36 +0000 (+0800) Subject: chore: update X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=89d5cf312c5e05d026719f1ddf0b6653a72ce571;p=thirdparty%2Fvuejs%2Fcore.git chore: update --- diff --git a/packages/runtime-dom/src/directives/vModel.ts b/packages/runtime-dom/src/directives/vModel.ts index 3c5e9fa933..a3a68b78f7 100644 --- a/packages/runtime-dom/src/directives/vModel.ts +++ b/packages/runtime-dom/src/directives/vModel.ts @@ -122,9 +122,6 @@ export const vModelCheckbox: ModelDirective = { deep: true, created(el, _, vnode) { el[assignKey] = getModelAssigner(vnode) - addEventListener(el, 'click', () => { - ;(el as any)._willChange = true - }) addEventListener(el, 'change', () => { const modelValue = (el as any)._modelValue const elementValue = getValue(el) @@ -156,10 +153,6 @@ export const vModelCheckbox: ModelDirective = { // set initial checked on mount to wait for true-value/false-value mounted: setChecked, beforeUpdate(el, binding, vnode) { - if ((el as any)._willChange) { - ;(el as any)._willChange = false - return - } el[assignKey] = getModelAssigner(vnode) setChecked(el, binding, vnode) }, @@ -170,9 +163,17 @@ function setChecked( { value }: DirectiveBinding, vnode: VNode, ) { + if (looseEqual(value, (el as any)._cachedValue)) { + return + } // store the v-model value on the element so it can be accessed by the // change listener. ;(el as any)._modelValue = value + ;(el as any)._cachedValue = isArray(value) + ? [...value] + : isSet(value) + ? new Set(value) + : value let checked: boolean if (isArray(value)) { @@ -210,22 +211,20 @@ export const vModelSelect: ModelDirective = { deep: true, created(el, { value, modifiers: { number } }, vnode) { const isSetModel = isSet(value) - addEventListener(el, 'click', () => { - ;(el as any)._willChange = true - }) addEventListener(el, 'change', () => { const selectedVal = Array.prototype.filter .call(el.options, (o: HTMLOptionElement) => o.selected) .map((o: HTMLOptionElement) => number ? looseToNumber(getValue(o)) : getValue(o), ) - el[assignKey]( - el.multiple - ? isSetModel - ? new Set(selectedVal) - : selectedVal - : selectedVal[0], - ) + const modelValue = el.multiple + ? isSetModel + ? new Set(selectedVal) + : selectedVal + : selectedVal[0] + el[assignKey](modelValue) + ;(el as any)._cachedValue = isArray(value) ? [...value] : value + el._assigning = true nextTick(() => { el._assigning = false @@ -243,16 +242,21 @@ export const vModelSelect: ModelDirective = { }, updated(el, { value }) { if (!el._assigning) { - if ((el as any)._willChange) { - ;(el as any)._willChange = false - return - } setSelected(el, value) } }, } function setSelected(el: HTMLSelectElement, value: any) { + if (looseEqual(value, (el as any)._cachedValue)) { + return + } + ;(el as any)._cachedValue = isArray(value) + ? [...value] + : isSet(value) + ? new Set(value) + : value + const isMultiple = el.multiple const isArrayValue = isArray(value) if (isMultiple && !isArrayValue && !isSet(value)) { diff --git a/packages/shared/src/looseEqual.ts b/packages/shared/src/looseEqual.ts index 9e71767219..54f222dc04 100644 --- a/packages/shared/src/looseEqual.ts +++ b/packages/shared/src/looseEqual.ts @@ -1,4 +1,4 @@ -import { isArray, isDate, isObject, isSymbol } from './general' +import { isArray, isDate, isObject, isSet, isSymbol } from './general' function looseCompareArrays(a: any[], b: any[]) { if (a.length !== b.length) return false @@ -9,6 +9,17 @@ function looseCompareArrays(a: any[], b: any[]) { return equal } +function looseCompareSets(a: Set, b: Set) { + if (a.size !== b.size) return false + let equal = true + a.forEach((v: any) => { + if (!b.has(v)) { + equal = false + } + }) + return equal +} + export function looseEqual(a: any, b: any): boolean { if (a === b) return true let aValidType = isDate(a) @@ -26,6 +37,13 @@ export function looseEqual(a: any, b: any): boolean { if (aValidType || bValidType) { return aValidType && bValidType ? looseCompareArrays(a, b) : false } + + aValidType = isSet(a) + bValidType = isSet(b) + if (aValidType || bValidType) { + return aValidType && bValidType ? looseCompareSets(a, b) : false + } + aValidType = isObject(a) bValidType = isObject(b) if (aValidType || bValidType) {