]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
chore: update
authordaiwei <daiwei521@126.com>
Sat, 12 Oct 2024 06:56:36 +0000 (14:56 +0800)
committerdaiwei <daiwei521@126.com>
Sat, 12 Oct 2024 06:56:36 +0000 (14:56 +0800)
packages/runtime-dom/src/directives/vModel.ts
packages/shared/src/looseEqual.ts

index 3c5e9fa933fb279b05b2029b06ba99799a10e9c9..a3a68b78f7f5f3069b2c04164aeffa44b6ac2cf0 100644 (file)
@@ -122,9 +122,6 @@ export const vModelCheckbox: ModelDirective<HTMLInputElement> = {
   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<HTMLInputElement> = {
   // 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<HTMLSelectElement, 'number'> = {
   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<HTMLSelectElement, 'number'> = {
   },
   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)) {
index 9e71767219c052a0532f68d93db593bdb9437eca..54f222dc044d8f3a0fcdc1c7909e1d082d177fce 100644 (file)
@@ -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<any>, b: Set<any>) {
+  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) {