parent
c23153d82e
commit
2937530bef
@ -390,12 +390,12 @@ export function createPathGetter(ctx: any, path: string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function traverse(value: unknown, seen: Set<unknown> = new Set()) {
|
export function traverse(value: unknown, seen: Set<unknown> = new Set()) {
|
||||||
if (
|
if (!isObject(value) || (value as any)[ReactiveFlags.SKIP]) {
|
||||||
!isObject(value) ||
|
return value
|
||||||
seen.has(value) ||
|
}
|
||||||
(value as any)[ReactiveFlags.SKIP]
|
seen = seen || new Set()
|
||||||
) {
|
if (seen.has(value)) {
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
seen.add(value)
|
seen.add(value)
|
||||||
|
@ -20,6 +20,7 @@ import { callWithAsyncErrorHandling, ErrorCodes } from './errorHandling'
|
|||||||
import { ComponentPublicInstance } from './componentPublicInstance'
|
import { ComponentPublicInstance } from './componentPublicInstance'
|
||||||
import { mapCompatDirectiveHook } from './compat/customDirective'
|
import { mapCompatDirectiveHook } from './compat/customDirective'
|
||||||
import { pauseTracking, resetTracking } from '@vue/reactivity'
|
import { pauseTracking, resetTracking } from '@vue/reactivity'
|
||||||
|
import { traverse } from './apiWatch'
|
||||||
|
|
||||||
export interface DirectiveBinding<V = any> {
|
export interface DirectiveBinding<V = any> {
|
||||||
instance: ComponentPublicInstance | null
|
instance: ComponentPublicInstance | null
|
||||||
@ -51,6 +52,7 @@ export interface ObjectDirective<T = any, V = any> {
|
|||||||
beforeUnmount?: DirectiveHook<T, null, V>
|
beforeUnmount?: DirectiveHook<T, null, V>
|
||||||
unmounted?: DirectiveHook<T, null, V>
|
unmounted?: DirectiveHook<T, null, V>
|
||||||
getSSRProps?: SSRDirectiveHook
|
getSSRProps?: SSRDirectiveHook
|
||||||
|
deep?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export type FunctionDirective<T = any, V = any> = DirectiveHook<T, any, V>
|
export type FunctionDirective<T = any, V = any> = DirectiveHook<T, any, V>
|
||||||
@ -101,6 +103,9 @@ export function withDirectives<T extends VNode>(
|
|||||||
updated: dir
|
updated: dir
|
||||||
} as ObjectDirective
|
} as ObjectDirective
|
||||||
}
|
}
|
||||||
|
if (dir.deep) {
|
||||||
|
traverse(value)
|
||||||
|
}
|
||||||
bindings.push({
|
bindings.push({
|
||||||
dir,
|
dir,
|
||||||
instance,
|
instance,
|
||||||
|
@ -99,6 +99,8 @@ export const vModelText: ModelDirective<
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const vModelCheckbox: ModelDirective<HTMLInputElement> = {
|
export const vModelCheckbox: ModelDirective<HTMLInputElement> = {
|
||||||
|
// #4096 array checkboxes need to be deep traversed
|
||||||
|
deep: true,
|
||||||
created(el, _, vnode) {
|
created(el, _, vnode) {
|
||||||
el._assign = getModelAssigner(vnode)
|
el._assign = getModelAssigner(vnode)
|
||||||
addEventListener(el, 'change', () => {
|
addEventListener(el, 'change', () => {
|
||||||
@ -171,6 +173,8 @@ export const vModelRadio: ModelDirective<HTMLInputElement> = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const vModelSelect: ModelDirective<HTMLSelectElement> = {
|
export const vModelSelect: ModelDirective<HTMLSelectElement> = {
|
||||||
|
// <select multiple> value need to be deep traversed
|
||||||
|
deep: true,
|
||||||
created(el, { value, modifiers: { number } }, vnode) {
|
created(el, { value, modifiers: { number } }, vnode) {
|
||||||
const isSetModel = isSet(value)
|
const isSetModel = isSet(value)
|
||||||
addEventListener(el, 'change', () => {
|
addEventListener(el, 'change', () => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user