mirror of https://github.com/vuejs/core.git
refactor(runtime-core): useModel work with vapor mode (#12666)
This commit is contained in:
parent
8008509aac
commit
139448556d
|
@ -366,6 +366,7 @@ export interface GenericComponentInstance {
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
refs: Data
|
refs: Data
|
||||||
|
emit: EmitFn
|
||||||
/**
|
/**
|
||||||
* used for keeping track of .once event handlers on components
|
* used for keeping track of .once event handlers on components
|
||||||
* @internal
|
* @internal
|
||||||
|
@ -377,6 +378,11 @@ export interface GenericComponentInstance {
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
propsDefaults: Data | null
|
propsDefaults: Data | null
|
||||||
|
/**
|
||||||
|
* used for getting the keys of a component's raw props, vapor only
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
rawKeys?: () => string[]
|
||||||
|
|
||||||
// exposed properties via expose()
|
// exposed properties via expose()
|
||||||
exposed: Record<string, any> | null
|
exposed: Record<string, any> | null
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
import { type Ref, customRef, ref } from '@vue/reactivity'
|
import { type Ref, customRef, ref } from '@vue/reactivity'
|
||||||
import { EMPTY_OBJ, camelize, hasChanged, hyphenate } from '@vue/shared'
|
import { EMPTY_OBJ, camelize, hasChanged, hyphenate } from '@vue/shared'
|
||||||
import type { DefineModelOptions, ModelRef } from '../apiSetupHelpers'
|
import type { DefineModelOptions, ModelRef } from '../apiSetupHelpers'
|
||||||
import { getCurrentInstance } from '../component'
|
import {
|
||||||
|
type ComponentInternalInstance,
|
||||||
|
getCurrentGenericInstance,
|
||||||
|
} from '../component'
|
||||||
import { warn } from '../warning'
|
import { warn } from '../warning'
|
||||||
import type { NormalizedProps } from '../componentProps'
|
import type { NormalizedProps } from '../componentProps'
|
||||||
import { watchSyncEffect } from '../apiWatch'
|
import { watchSyncEffect } from '../apiWatch'
|
||||||
|
@ -23,14 +26,14 @@ export function useModel(
|
||||||
name: string,
|
name: string,
|
||||||
options: DefineModelOptions = EMPTY_OBJ,
|
options: DefineModelOptions = EMPTY_OBJ,
|
||||||
): Ref {
|
): Ref {
|
||||||
const i = getCurrentInstance()!
|
const i = getCurrentGenericInstance()!
|
||||||
if (__DEV__ && !i) {
|
if (__DEV__ && !i) {
|
||||||
warn(`useModel() called without active instance.`)
|
warn(`useModel() called without active instance.`)
|
||||||
return ref() as any
|
return ref() as any
|
||||||
}
|
}
|
||||||
|
|
||||||
const camelizedName = camelize(name)
|
const camelizedName = camelize(name)
|
||||||
if (__DEV__ && !(i.propsOptions[0] as NormalizedProps)[camelizedName]) {
|
if (__DEV__ && !(i.propsOptions![0] as NormalizedProps)[camelizedName]) {
|
||||||
warn(`useModel() called with prop "${name}" which is not declared.`)
|
warn(`useModel() called with prop "${name}" which is not declared.`)
|
||||||
return ref() as any
|
return ref() as any
|
||||||
}
|
}
|
||||||
|
@ -65,19 +68,38 @@ export function useModel(
|
||||||
) {
|
) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const rawProps = i.vnode!.props
|
|
||||||
|
let rawPropKeys
|
||||||
|
let parentPassedModelValue = false
|
||||||
|
let parentPassedModelUpdater = false
|
||||||
|
|
||||||
|
if (i.rawKeys) {
|
||||||
|
// vapor instance
|
||||||
|
rawPropKeys = i.rawKeys()
|
||||||
|
} else {
|
||||||
|
const rawProps = (i as ComponentInternalInstance).vnode!.props
|
||||||
|
rawPropKeys = rawProps && Object.keys(rawProps)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rawPropKeys) {
|
||||||
|
for (const key of rawPropKeys) {
|
||||||
if (
|
if (
|
||||||
!(
|
key === name ||
|
||||||
rawProps &&
|
key === camelizedName ||
|
||||||
// check if parent has passed v-model
|
key === hyphenatedName
|
||||||
(name in rawProps ||
|
|
||||||
camelizedName in rawProps ||
|
|
||||||
hyphenatedName in rawProps) &&
|
|
||||||
(`onUpdate:${name}` in rawProps ||
|
|
||||||
`onUpdate:${camelizedName}` in rawProps ||
|
|
||||||
`onUpdate:${hyphenatedName}` in rawProps)
|
|
||||||
)
|
|
||||||
) {
|
) {
|
||||||
|
parentPassedModelValue = true
|
||||||
|
} else if (
|
||||||
|
key === `onUpdate:${name}` ||
|
||||||
|
key === `onUpdate:${camelizedName}` ||
|
||||||
|
key === `onUpdate:${hyphenatedName}`
|
||||||
|
) {
|
||||||
|
parentPassedModelUpdater = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!parentPassedModelValue || !parentPassedModelUpdater) {
|
||||||
// no v-model, local update
|
// no v-model, local update
|
||||||
localValue = value
|
localValue = value
|
||||||
trigger()
|
trigger()
|
||||||
|
|
|
@ -50,6 +50,7 @@ import {
|
||||||
import {
|
import {
|
||||||
type DynamicPropsSource,
|
type DynamicPropsSource,
|
||||||
type RawProps,
|
type RawProps,
|
||||||
|
getKeysFromRawProps,
|
||||||
getPropsProxyHandlers,
|
getPropsProxyHandlers,
|
||||||
hasFallthroughAttrs,
|
hasFallthroughAttrs,
|
||||||
normalizePropsOptions,
|
normalizePropsOptions,
|
||||||
|
@ -410,6 +411,14 @@ export class VaporComponentInstance implements GenericComponentInstance {
|
||||||
this.emitsOptions = normalizeEmitsOptions(comp)
|
this.emitsOptions = normalizeEmitsOptions(comp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expose `getKeysFromRawProps` on the instance so it can be used in code
|
||||||
|
* paths where it's needed, e.g. `useModel`
|
||||||
|
*/
|
||||||
|
rawKeys(): string[] {
|
||||||
|
return getKeysFromRawProps(this.rawProps)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isVaporComponent(
|
export function isVaporComponent(
|
||||||
|
|
Loading…
Reference in New Issue