-
-
Notifications
You must be signed in to change notification settings - Fork 8.4k
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,7 +11,9 @@ import { | |
looseEqual, | ||
looseIndexOf, | ||
invokeArrayFns, | ||
toNumber | ||
toNumber, | ||
isSet, | ||
looseHas | ||
} from '@vue/shared' | ||
|
||
type AssignerFn = (value: any) => void | ||
|
@@ -111,6 +113,14 @@ export const vModelCheckbox: ModelDirective<HTMLInputElement> = { | |
filtered.splice(index, 1) | ||
assign(filtered) | ||
} | ||
} else if (isSet(modelValue)) { | ||
const found = modelValue.has(elementValue) | ||
if (checked && !found) { | ||
assign(modelValue.add(elementValue)) | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
jods4
Contributor
|
||
} else if (!checked && found) { | ||
modelValue.delete(elementValue) | ||
assign(modelValue) | ||
} | ||
} else { | ||
assign(getCheckboxValue(el, checked)) | ||
} | ||
|
@@ -132,6 +142,8 @@ function setChecked( | |
;(el as any)._modelValue = value | ||
if (isArray(value)) { | ||
el.checked = looseIndexOf(value, vnode.props!.value) > -1 | ||
} else if (isSet(value)) { | ||
el.checked = looseHas(value, vnode.props!.value) | ||
} else if (value !== oldValue) { | ||
el.checked = looseEqual(value, getCheckboxValue(el, true)) | ||
} | ||
|
@@ -178,10 +190,10 @@ export const vModelSelect: ModelDirective<HTMLSelectElement> = { | |
|
||
function setSelected(el: HTMLSelectElement, value: any) { | ||
const isMultiple = el.multiple | ||
if (isMultiple && !isArray(value)) { | ||
if (isMultiple && !isArray(value) && !isSet(value)) { | ||
__DEV__ && | ||
warn( | ||
`<select multiple v-model> expects an Array value for its binding, ` + | ||
`<select multiple v-model> expects an Array or Set value for its binding, ` + | ||
`but got ${Object.prototype.toString.call(value).slice(8, -1)}.` | ||
) | ||
return | ||
|
@@ -190,7 +202,11 @@ function setSelected(el: HTMLSelectElement, value: any) { | |
const option = el.options[i] | ||
const optionValue = getValue(option) | ||
if (isMultiple) { | ||
option.selected = looseIndexOf(value, optionValue) > -1 | ||
if (isArray(value)) { | ||
option.selected = looseIndexOf(value, optionValue) > -1 | ||
} else { | ||
option.selected = looseHas(value, optionValue) | ||
} | ||
} else { | ||
if (looseEqual(getValue(option), value)) { | ||
el.selectedIndex = i | ||
|
@@ -280,6 +296,10 @@ if (__NODE_JS__) { | |
if (vnode.props && looseIndexOf(value, vnode.props.value) > -1) { | ||
return { checked: true } | ||
} | ||
} else if (isSet(value)) { | ||
if (vnode.props && looseHas(value, vnode.props.value)) { | ||
return { checked: true } | ||
} | ||
} else if (value) { | ||
return { checked: true } | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -58,6 +58,9 @@ export const hasOwn = ( | |
): key is keyof typeof val => hasOwnProperty.call(val, key) | ||
|
||
export const isArray = Array.isArray | ||
export const isSet = (val: any): boolean => { | ||
return toRawType(val) === 'Set' | ||
This comment has been minimized.
Sorry, something went wrong.
jods4
Contributor
|
||
} | ||
export const isDate = (val: unknown): val is Date => val instanceof Date | ||
export const isFunction = (val: unknown): val is Function => | ||
typeof val === 'function' | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -51,3 +51,10 @@ export function looseEqual(a: any, b: any): boolean { | |
export function looseIndexOf(arr: any[], val: any): number { | ||
return arr.findIndex(item => looseEqual(item, val)) | ||
} | ||
|
||
export function looseHas(set: Set<any>, val: any): boolean { | ||
This comment has been minimized.
Sorry, something went wrong.
jods4
Contributor
|
||
for (let item of set) { | ||
if (looseEqual(item, val)) return true | ||
} | ||
return false | ||
} |
Great feature!
Why call
assign
here?Unlike arrays, which are replaced by a new instance, this code mutates the
Set
, somodelValue
has not changed, soassign
seems unneeded to me.Once
assign
is removed, theSet::has
check is meaningless asSet::add
does check if the element is already in there or not. Same forSet:delete
. So code can be reduced to: