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