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
|
||||
*/
|
||||
refs: Data
|
||||
emit: EmitFn
|
||||
/**
|
||||
* used for keeping track of .once event handlers on components
|
||||
* @internal
|
||||
|
@ -377,6 +378,11 @@ export interface GenericComponentInstance {
|
|||
* @internal
|
||||
*/
|
||||
propsDefaults: Data | null
|
||||
/**
|
||||
* used for getting the keys of a component's raw props, vapor only
|
||||
* @internal
|
||||
*/
|
||||
rawKeys?: () => string[]
|
||||
|
||||
// exposed properties via expose()
|
||||
exposed: Record<string, any> | null
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
import { type Ref, customRef, ref } from '@vue/reactivity'
|
||||
import { EMPTY_OBJ, camelize, hasChanged, hyphenate } from '@vue/shared'
|
||||
import type { DefineModelOptions, ModelRef } from '../apiSetupHelpers'
|
||||
import { getCurrentInstance } from '../component'
|
||||
import {
|
||||
type ComponentInternalInstance,
|
||||
getCurrentGenericInstance,
|
||||
} from '../component'
|
||||
import { warn } from '../warning'
|
||||
import type { NormalizedProps } from '../componentProps'
|
||||
import { watchSyncEffect } from '../apiWatch'
|
||||
|
@ -23,14 +26,14 @@ export function useModel(
|
|||
name: string,
|
||||
options: DefineModelOptions = EMPTY_OBJ,
|
||||
): Ref {
|
||||
const i = getCurrentInstance()!
|
||||
const i = getCurrentGenericInstance()!
|
||||
if (__DEV__ && !i) {
|
||||
warn(`useModel() called without active instance.`)
|
||||
return ref() as any
|
||||
}
|
||||
|
||||
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.`)
|
||||
return ref() as any
|
||||
}
|
||||
|
@ -65,19 +68,38 @@ export function useModel(
|
|||
) {
|
||||
return
|
||||
}
|
||||
const rawProps = i.vnode!.props
|
||||
if (
|
||||
!(
|
||||
rawProps &&
|
||||
// check if parent has passed v-model
|
||||
(name in rawProps ||
|
||||
camelizedName in rawProps ||
|
||||
hyphenatedName in rawProps) &&
|
||||
(`onUpdate:${name}` in rawProps ||
|
||||
`onUpdate:${camelizedName}` in rawProps ||
|
||||
`onUpdate:${hyphenatedName}` in rawProps)
|
||||
)
|
||||
) {
|
||||
|
||||
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 (
|
||||
key === name ||
|
||||
key === camelizedName ||
|
||||
key === hyphenatedName
|
||||
) {
|
||||
parentPassedModelValue = true
|
||||
} else if (
|
||||
key === `onUpdate:${name}` ||
|
||||
key === `onUpdate:${camelizedName}` ||
|
||||
key === `onUpdate:${hyphenatedName}`
|
||||
) {
|
||||
parentPassedModelUpdater = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!parentPassedModelValue || !parentPassedModelUpdater) {
|
||||
// no v-model, local update
|
||||
localValue = value
|
||||
trigger()
|
||||
|
|
|
@ -50,6 +50,7 @@ import {
|
|||
import {
|
||||
type DynamicPropsSource,
|
||||
type RawProps,
|
||||
getKeysFromRawProps,
|
||||
getPropsProxyHandlers,
|
||||
hasFallthroughAttrs,
|
||||
normalizePropsOptions,
|
||||
|
@ -410,6 +411,14 @@ export class VaporComponentInstance implements GenericComponentInstance {
|
|||
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(
|
||||
|
|
Loading…
Reference in New Issue