This commit is contained in:
yangchangtao 2024-11-18 17:16:04 +08:00
parent 6eb29d345a
commit 030553eb63
1 changed files with 18 additions and 12 deletions

View File

@ -4,6 +4,7 @@ import {
type ObjectDirective,
type VNode,
nextTick,
toRaw,
warn,
} from '@vue/runtime-core'
import { addEventListener } from '../modules/events'
@ -38,9 +39,15 @@ function onCompositionEnd(e: Event) {
}
const assignKey: unique symbol = Symbol('_assign')
const assignValueKey: unique symbol = Symbol('_value')
const assigningKey: unique symbol = Symbol('_assigning')
type ModelDirective<T, Modifiers extends string = string> = ObjectDirective<
T & { [assignKey]: AssignerFn; _assigning?: boolean },
T & {
[assignKey]: AssignerFn
[assignValueKey]: any
[assigningKey]?: boolean
},
any,
Modifiers
>
@ -202,7 +209,7 @@ export const vModelRadio: ModelDirective<HTMLInputElement> = {
export const vModelSelect: ModelDirective<HTMLSelectElement, 'number'> = {
// <select multiple> value need to be deep traversed
deep: true,
created(el, { value, modifiers: { number } }, vnode) {
created(el, { value, oldValue, modifiers: { number } }, vnode) {
const isSetModel = isSet(value)
addEventListener(el, 'change', () => {
const selectedVal = Array.prototype.filter
@ -210,16 +217,15 @@ export const vModelSelect: ModelDirective<HTMLSelectElement, 'number'> = {
.map((o: HTMLOptionElement) =>
number ? looseToNumber(getValue(o)) : getValue(o),
)
el[assignKey](
el.multiple
? isSetModel
? new Set(selectedVal)
: selectedVal
: selectedVal[0],
)
el._assigning = true
const value = (el[assignValueKey] = el.multiple
? isSetModel
? new Set(selectedVal)
: selectedVal
: selectedVal[0])
el[assignKey](value)
el[assigningKey] = true
nextTick(() => {
el._assigning = false
el[assigningKey] = false
})
})
el[assignKey] = getModelAssigner(vnode)
@ -233,7 +239,7 @@ export const vModelSelect: ModelDirective<HTMLSelectElement, 'number'> = {
el[assignKey] = getModelAssigner(vnode)
},
updated(el, { value }) {
if (!el._assigning) {
if (!el[assigningKey] || toRaw(value) !== el[assignValueKey]) {
setSelected(el, value)
}
},