types: massive refactor
This commit is contained in:
parent
522beaa766
commit
b5886189ba
@ -12,7 +12,7 @@ const builtInSymbols = new Set(
|
|||||||
)
|
)
|
||||||
|
|
||||||
function createGetter(isReadonly: boolean) {
|
function createGetter(isReadonly: boolean) {
|
||||||
return function get(target: any, key: string | symbol, receiver: any) {
|
return function get(target: object, key: string | symbol, receiver: object) {
|
||||||
const res = Reflect.get(target, key, receiver)
|
const res = Reflect.get(target, key, receiver)
|
||||||
if (isSymbol(key) && builtInSymbols.has(key)) {
|
if (isSymbol(key) && builtInSymbols.has(key)) {
|
||||||
return res
|
return res
|
||||||
@ -32,13 +32,13 @@ function createGetter(isReadonly: boolean) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function set(
|
function set(
|
||||||
target: any,
|
target: object,
|
||||||
key: string | symbol,
|
key: string | symbol,
|
||||||
value: any,
|
value: unknown,
|
||||||
receiver: any
|
receiver: object
|
||||||
): boolean {
|
): boolean {
|
||||||
value = toRaw(value)
|
value = toRaw(value)
|
||||||
const oldValue = target[key]
|
const oldValue = (target as any)[key]
|
||||||
if (isRef(oldValue) && !isRef(value)) {
|
if (isRef(oldValue) && !isRef(value)) {
|
||||||
oldValue.value = value
|
oldValue.value = value
|
||||||
return true
|
return true
|
||||||
@ -66,9 +66,9 @@ function set(
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteProperty(target: any, key: string | symbol): boolean {
|
function deleteProperty(target: object, key: string | symbol): boolean {
|
||||||
const hadKey = hasOwn(target, key)
|
const hadKey = hasOwn(target, key)
|
||||||
const oldValue = target[key]
|
const oldValue = (target as any)[key]
|
||||||
const result = Reflect.deleteProperty(target, key)
|
const result = Reflect.deleteProperty(target, key)
|
||||||
if (result && hadKey) {
|
if (result && hadKey) {
|
||||||
/* istanbul ignore else */
|
/* istanbul ignore else */
|
||||||
@ -81,18 +81,18 @@ function deleteProperty(target: any, key: string | symbol): boolean {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
function has(target: any, key: string | symbol): boolean {
|
function has(target: object, key: string | symbol): boolean {
|
||||||
const result = Reflect.has(target, key)
|
const result = Reflect.has(target, key)
|
||||||
track(target, OperationTypes.HAS, key)
|
track(target, OperationTypes.HAS, key)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
function ownKeys(target: any): (string | number | symbol)[] {
|
function ownKeys(target: object): (string | number | symbol)[] {
|
||||||
track(target, OperationTypes.ITERATE)
|
track(target, OperationTypes.ITERATE)
|
||||||
return Reflect.ownKeys(target)
|
return Reflect.ownKeys(target)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const mutableHandlers: ProxyHandler<any> = {
|
export const mutableHandlers: ProxyHandler<object> = {
|
||||||
get: createGetter(false),
|
get: createGetter(false),
|
||||||
set,
|
set,
|
||||||
deleteProperty,
|
deleteProperty,
|
||||||
@ -100,10 +100,15 @@ export const mutableHandlers: ProxyHandler<any> = {
|
|||||||
ownKeys
|
ownKeys
|
||||||
}
|
}
|
||||||
|
|
||||||
export const readonlyHandlers: ProxyHandler<any> = {
|
export const readonlyHandlers: ProxyHandler<object> = {
|
||||||
get: createGetter(true),
|
get: createGetter(true),
|
||||||
|
|
||||||
set(target: any, key: string | symbol, value: any, receiver: any): boolean {
|
set(
|
||||||
|
target: object,
|
||||||
|
key: string | symbol,
|
||||||
|
value: unknown,
|
||||||
|
receiver: object
|
||||||
|
): boolean {
|
||||||
if (LOCKED) {
|
if (LOCKED) {
|
||||||
if (__DEV__) {
|
if (__DEV__) {
|
||||||
console.warn(
|
console.warn(
|
||||||
@ -117,7 +122,7 @@ export const readonlyHandlers: ProxyHandler<any> = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
deleteProperty(target: any, key: string | symbol): boolean {
|
deleteProperty(target: object, key: string | symbol): boolean {
|
||||||
if (LOCKED) {
|
if (LOCKED) {
|
||||||
if (__DEV__) {
|
if (__DEV__) {
|
||||||
console.warn(
|
console.warn(
|
||||||
|
@ -4,43 +4,56 @@ import { OperationTypes } from './operations'
|
|||||||
import { LOCKED } from './lock'
|
import { LOCKED } from './lock'
|
||||||
import { isObject, capitalize, hasOwn } from '@vue/shared'
|
import { isObject, capitalize, hasOwn } from '@vue/shared'
|
||||||
|
|
||||||
const toReactive = (value: any) => (isObject(value) ? reactive(value) : value)
|
export type CollectionTypes = IterableCollections | WeakCollections
|
||||||
const toReadonly = (value: any) => (isObject(value) ? readonly(value) : value)
|
|
||||||
|
|
||||||
function get(target: any, key: any, wrap: (t: any) => any): any {
|
type IterableCollections = Map<any, any> | Set<any>
|
||||||
|
type WeakCollections = WeakMap<any, any> | WeakSet<any>
|
||||||
|
type MapTypes = Map<any, any> | WeakMap<any, any>
|
||||||
|
type SetTypes = Set<any> | WeakSet<any>
|
||||||
|
|
||||||
|
const toReactive = <T extends unknown>(value: T): T =>
|
||||||
|
isObject(value) ? reactive(value) : value
|
||||||
|
|
||||||
|
const toReadonly = <T extends unknown>(value: T): T =>
|
||||||
|
isObject(value) ? readonly(value) : value
|
||||||
|
|
||||||
|
const getProto = <T extends CollectionTypes>(v: T): any =>
|
||||||
|
Reflect.getPrototypeOf(v)
|
||||||
|
|
||||||
|
function get(
|
||||||
|
target: MapTypes,
|
||||||
|
key: unknown,
|
||||||
|
wrap: typeof toReactive | typeof toReadonly
|
||||||
|
) {
|
||||||
target = toRaw(target)
|
target = toRaw(target)
|
||||||
key = toRaw(key)
|
key = toRaw(key)
|
||||||
const proto: any = Reflect.getPrototypeOf(target)
|
|
||||||
track(target, OperationTypes.GET, key)
|
track(target, OperationTypes.GET, key)
|
||||||
const res = proto.get.call(target, key)
|
return wrap(getProto(target).get.call(target, key))
|
||||||
return wrap(res)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function has(this: any, key: any): boolean {
|
function has(this: CollectionTypes, key: unknown): boolean {
|
||||||
const target = toRaw(this)
|
const target = toRaw(this)
|
||||||
key = toRaw(key)
|
key = toRaw(key)
|
||||||
const proto: any = Reflect.getPrototypeOf(target)
|
|
||||||
track(target, OperationTypes.HAS, key)
|
track(target, OperationTypes.HAS, key)
|
||||||
return proto.has.call(target, key)
|
return getProto(target).has.call(target, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
function size(target: any) {
|
function size(target: IterableCollections) {
|
||||||
target = toRaw(target)
|
target = toRaw(target)
|
||||||
const proto = Reflect.getPrototypeOf(target)
|
|
||||||
track(target, OperationTypes.ITERATE)
|
track(target, OperationTypes.ITERATE)
|
||||||
return Reflect.get(proto, 'size', target)
|
return Reflect.get(getProto(target), 'size', target)
|
||||||
}
|
}
|
||||||
|
|
||||||
function add(this: any, value: any) {
|
function add(this: SetTypes, value: unknown) {
|
||||||
value = toRaw(value)
|
value = toRaw(value)
|
||||||
const target = toRaw(this)
|
const target = toRaw(this)
|
||||||
const proto: any = Reflect.getPrototypeOf(this)
|
const proto = getProto(target)
|
||||||
const hadKey = proto.has.call(target, value)
|
const hadKey = proto.has.call(target, value)
|
||||||
const result = proto.add.call(target, value)
|
const result = proto.add.call(target, value)
|
||||||
if (!hadKey) {
|
if (!hadKey) {
|
||||||
/* istanbul ignore else */
|
/* istanbul ignore else */
|
||||||
if (__DEV__) {
|
if (__DEV__) {
|
||||||
trigger(target, OperationTypes.ADD, value, { value })
|
trigger(target, OperationTypes.ADD, value, { newValue: value })
|
||||||
} else {
|
} else {
|
||||||
trigger(target, OperationTypes.ADD, value)
|
trigger(target, OperationTypes.ADD, value)
|
||||||
}
|
}
|
||||||
@ -48,10 +61,10 @@ function add(this: any, value: any) {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
function set(this: any, key: any, value: any) {
|
function set(this: MapTypes, key: unknown, value: unknown) {
|
||||||
value = toRaw(value)
|
value = toRaw(value)
|
||||||
const target = toRaw(this)
|
const target = toRaw(this)
|
||||||
const proto: any = Reflect.getPrototypeOf(this)
|
const proto = getProto(target)
|
||||||
const hadKey = proto.has.call(target, key)
|
const hadKey = proto.has.call(target, key)
|
||||||
const oldValue = proto.get.call(target, key)
|
const oldValue = proto.get.call(target, key)
|
||||||
const result = proto.set.call(target, key, value)
|
const result = proto.set.call(target, key, value)
|
||||||
@ -75,9 +88,9 @@ function set(this: any, key: any, value: any) {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteEntry(this: any, key: any) {
|
function deleteEntry(this: CollectionTypes, key: unknown) {
|
||||||
const target = toRaw(this)
|
const target = toRaw(this)
|
||||||
const proto: any = Reflect.getPrototypeOf(this)
|
const proto = getProto(target)
|
||||||
const hadKey = proto.has.call(target, key)
|
const hadKey = proto.has.call(target, key)
|
||||||
const oldValue = proto.get ? proto.get.call(target, key) : undefined
|
const oldValue = proto.get ? proto.get.call(target, key) : undefined
|
||||||
// forward the operation before queueing reactions
|
// forward the operation before queueing reactions
|
||||||
@ -93,13 +106,16 @@ function deleteEntry(this: any, key: any) {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
function clear(this: any) {
|
function clear(this: IterableCollections) {
|
||||||
const target = toRaw(this)
|
const target = toRaw(this)
|
||||||
const proto: any = Reflect.getPrototypeOf(this)
|
|
||||||
const hadItems = target.size !== 0
|
const hadItems = target.size !== 0
|
||||||
const oldTarget = target instanceof Map ? new Map(target) : new Set(target)
|
const oldTarget = __DEV__
|
||||||
|
? target instanceof Map
|
||||||
|
? new Map(target)
|
||||||
|
: new Set(target)
|
||||||
|
: undefined
|
||||||
// forward the operation before queueing reactions
|
// forward the operation before queueing reactions
|
||||||
const result = proto.clear.call(target)
|
const result = getProto(target).clear.call(target)
|
||||||
if (hadItems) {
|
if (hadItems) {
|
||||||
/* istanbul ignore else */
|
/* istanbul ignore else */
|
||||||
if (__DEV__) {
|
if (__DEV__) {
|
||||||
@ -112,30 +128,32 @@ function clear(this: any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function createForEach(isReadonly: boolean) {
|
function createForEach(isReadonly: boolean) {
|
||||||
return function forEach(this: any, callback: Function, thisArg?: any) {
|
return function forEach(
|
||||||
|
this: IterableCollections,
|
||||||
|
callback: Function,
|
||||||
|
thisArg?: unknown
|
||||||
|
) {
|
||||||
const observed = this
|
const observed = this
|
||||||
const target = toRaw(observed)
|
const target = toRaw(observed)
|
||||||
const proto: any = Reflect.getPrototypeOf(target)
|
|
||||||
const wrap = isReadonly ? toReadonly : toReactive
|
const wrap = isReadonly ? toReadonly : toReactive
|
||||||
track(target, OperationTypes.ITERATE)
|
track(target, OperationTypes.ITERATE)
|
||||||
// important: create sure the callback is
|
// important: create sure the callback is
|
||||||
// 1. invoked with the reactive map as `this` and 3rd arg
|
// 1. invoked with the reactive map as `this` and 3rd arg
|
||||||
// 2. the value received should be a corresponding reactive/readonly.
|
// 2. the value received should be a corresponding reactive/readonly.
|
||||||
function wrappedCallback(value: any, key: any) {
|
function wrappedCallback(value: unknown, key: unknown) {
|
||||||
return callback.call(observed, wrap(value), wrap(key), observed)
|
return callback.call(observed, wrap(value), wrap(key), observed)
|
||||||
}
|
}
|
||||||
return proto.forEach.call(target, wrappedCallback, thisArg)
|
return getProto(target).forEach.call(target, wrappedCallback, thisArg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function createIterableMethod(method: string | symbol, isReadonly: boolean) {
|
function createIterableMethod(method: string | symbol, isReadonly: boolean) {
|
||||||
return function(this: any, ...args: any[]) {
|
return function(this: IterableCollections, ...args: unknown[]) {
|
||||||
const target = toRaw(this)
|
const target = toRaw(this)
|
||||||
const proto: any = Reflect.getPrototypeOf(target)
|
|
||||||
const isPair =
|
const isPair =
|
||||||
method === 'entries' ||
|
method === 'entries' ||
|
||||||
(method === Symbol.iterator && target instanceof Map)
|
(method === Symbol.iterator && target instanceof Map)
|
||||||
const innerIterator = proto[method].apply(target, args)
|
const innerIterator = getProto(target)[method].apply(target, args)
|
||||||
const wrap = isReadonly ? toReadonly : toReactive
|
const wrap = isReadonly ? toReadonly : toReactive
|
||||||
track(target, OperationTypes.ITERATE)
|
track(target, OperationTypes.ITERATE)
|
||||||
// return a wrapped iterator which returns observed versions of the
|
// return a wrapped iterator which returns observed versions of the
|
||||||
@ -163,7 +181,7 @@ function createReadonlyMethod(
|
|||||||
method: Function,
|
method: Function,
|
||||||
type: OperationTypes
|
type: OperationTypes
|
||||||
): Function {
|
): Function {
|
||||||
return function(this: any, ...args: any[]) {
|
return function(this: CollectionTypes, ...args: unknown[]) {
|
||||||
if (LOCKED) {
|
if (LOCKED) {
|
||||||
if (__DEV__) {
|
if (__DEV__) {
|
||||||
const key = args[0] ? `on key "${args[0]}" ` : ``
|
const key = args[0] ? `on key "${args[0]}" ` : ``
|
||||||
@ -179,11 +197,11 @@ function createReadonlyMethod(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const mutableInstrumentations: any = {
|
const mutableInstrumentations: Record<string, Function> = {
|
||||||
get(key: any) {
|
get(this: MapTypes, key: unknown) {
|
||||||
return get(this, key, toReactive)
|
return get(this, key, toReactive)
|
||||||
},
|
},
|
||||||
get size() {
|
get size(this: IterableCollections) {
|
||||||
return size(this)
|
return size(this)
|
||||||
},
|
},
|
||||||
has,
|
has,
|
||||||
@ -194,11 +212,11 @@ const mutableInstrumentations: any = {
|
|||||||
forEach: createForEach(false)
|
forEach: createForEach(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
const readonlyInstrumentations: any = {
|
const readonlyInstrumentations: Record<string, Function> = {
|
||||||
get(key: any) {
|
get(this: MapTypes, key: unknown) {
|
||||||
return get(this, key, toReadonly)
|
return get(this, key, toReadonly)
|
||||||
},
|
},
|
||||||
get size() {
|
get size(this: IterableCollections) {
|
||||||
return size(this)
|
return size(this)
|
||||||
},
|
},
|
||||||
has,
|
has,
|
||||||
@ -211,26 +229,37 @@ const readonlyInstrumentations: any = {
|
|||||||
|
|
||||||
const iteratorMethods = ['keys', 'values', 'entries', Symbol.iterator]
|
const iteratorMethods = ['keys', 'values', 'entries', Symbol.iterator]
|
||||||
iteratorMethods.forEach(method => {
|
iteratorMethods.forEach(method => {
|
||||||
mutableInstrumentations[method] = createIterableMethod(method, false)
|
mutableInstrumentations[method as string] = createIterableMethod(
|
||||||
readonlyInstrumentations[method] = createIterableMethod(method, true)
|
method,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
readonlyInstrumentations[method as string] = createIterableMethod(
|
||||||
|
method,
|
||||||
|
true
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
function createInstrumentationGetter(instrumentations: any) {
|
function createInstrumentationGetter(
|
||||||
return function getInstrumented(
|
instrumentations: Record<string, Function>
|
||||||
target: any,
|
) {
|
||||||
|
return (
|
||||||
|
target: CollectionTypes,
|
||||||
key: string | symbol,
|
key: string | symbol,
|
||||||
receiver: any
|
receiver: CollectionTypes
|
||||||
) {
|
) =>
|
||||||
target =
|
Reflect.get(
|
||||||
hasOwn(instrumentations, key) && key in target ? instrumentations : target
|
hasOwn(instrumentations, key) && key in target
|
||||||
return Reflect.get(target, key, receiver)
|
? instrumentations
|
||||||
}
|
: target,
|
||||||
|
key,
|
||||||
|
receiver
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const mutableCollectionHandlers: ProxyHandler<any> = {
|
export const mutableCollectionHandlers: ProxyHandler<CollectionTypes> = {
|
||||||
get: createInstrumentationGetter(mutableInstrumentations)
|
get: createInstrumentationGetter(mutableInstrumentations)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const readonlyCollectionHandlers: ProxyHandler<any> = {
|
export const readonlyCollectionHandlers: ProxyHandler<CollectionTypes> = {
|
||||||
get: createInstrumentationGetter(readonlyInstrumentations)
|
get: createInstrumentationGetter(readonlyInstrumentations)
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ export function computed<T>(
|
|||||||
): WritableComputedRef<T>
|
): WritableComputedRef<T>
|
||||||
export function computed<T>(
|
export function computed<T>(
|
||||||
getterOrOptions: ComputedGetter<T> | WritableComputedOptions<T>
|
getterOrOptions: ComputedGetter<T> | WritableComputedOptions<T>
|
||||||
): any {
|
) {
|
||||||
const isReadonly = isFunction(getterOrOptions)
|
const isReadonly = isFunction(getterOrOptions)
|
||||||
const getter = isReadonly
|
const getter = isReadonly
|
||||||
? (getterOrOptions as ComputedGetter<T>)
|
? (getterOrOptions as ComputedGetter<T>)
|
||||||
|
@ -2,11 +2,9 @@ import { OperationTypes } from './operations'
|
|||||||
import { Dep, targetMap } from './reactive'
|
import { Dep, targetMap } from './reactive'
|
||||||
import { EMPTY_OBJ, extend } from '@vue/shared'
|
import { EMPTY_OBJ, extend } from '@vue/shared'
|
||||||
|
|
||||||
export const effectSymbol = Symbol(__DEV__ ? 'effect' : void 0)
|
|
||||||
|
|
||||||
export interface ReactiveEffect<T = any> {
|
export interface ReactiveEffect<T = any> {
|
||||||
(): T
|
(): T
|
||||||
[effectSymbol]: true
|
_isEffect: true
|
||||||
active: boolean
|
active: boolean
|
||||||
raw: () => T
|
raw: () => T
|
||||||
deps: Array<Dep>
|
deps: Array<Dep>
|
||||||
@ -26,11 +24,17 @@ export interface ReactiveEffectOptions {
|
|||||||
onStop?: () => void
|
onStop?: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DebuggerEvent {
|
type DebuggerEvent = {
|
||||||
effect: ReactiveEffect
|
effect: ReactiveEffect
|
||||||
target: any
|
target: object
|
||||||
type: OperationTypes
|
type: OperationTypes
|
||||||
key: string | symbol | undefined
|
key: any
|
||||||
|
} & DebuggerEventExtraInfo
|
||||||
|
|
||||||
|
export interface DebuggerEventExtraInfo {
|
||||||
|
newValue?: any
|
||||||
|
oldValue?: any
|
||||||
|
oldTarget?: Map<any, any> | Set<any>
|
||||||
}
|
}
|
||||||
|
|
||||||
export const effectStack: ReactiveEffect[] = []
|
export const effectStack: ReactiveEffect[] = []
|
||||||
@ -38,7 +42,7 @@ export const effectStack: ReactiveEffect[] = []
|
|||||||
export const ITERATE_KEY = Symbol('iterate')
|
export const ITERATE_KEY = Symbol('iterate')
|
||||||
|
|
||||||
export function isEffect(fn: any): fn is ReactiveEffect {
|
export function isEffect(fn: any): fn is ReactiveEffect {
|
||||||
return fn != null && fn[effectSymbol] === true
|
return fn != null && fn._isEffect === true
|
||||||
}
|
}
|
||||||
|
|
||||||
export function effect<T = any>(
|
export function effect<T = any>(
|
||||||
@ -69,10 +73,10 @@ function createReactiveEffect<T = any>(
|
|||||||
fn: () => T,
|
fn: () => T,
|
||||||
options: ReactiveEffectOptions
|
options: ReactiveEffectOptions
|
||||||
): ReactiveEffect<T> {
|
): ReactiveEffect<T> {
|
||||||
const effect = function reactiveEffect(...args: any[]): any {
|
const effect = function reactiveEffect(...args: unknown[]): unknown {
|
||||||
return run(effect, fn, args)
|
return run(effect, fn, args)
|
||||||
} as ReactiveEffect
|
} as ReactiveEffect
|
||||||
effect[effectSymbol] = true
|
effect._isEffect = true
|
||||||
effect.active = true
|
effect.active = true
|
||||||
effect.raw = fn
|
effect.raw = fn
|
||||||
effect.scheduler = options.scheduler
|
effect.scheduler = options.scheduler
|
||||||
@ -84,7 +88,7 @@ function createReactiveEffect<T = any>(
|
|||||||
return effect
|
return effect
|
||||||
}
|
}
|
||||||
|
|
||||||
function run(effect: ReactiveEffect, fn: Function, args: any[]): any {
|
function run(effect: ReactiveEffect, fn: Function, args: unknown[]): unknown {
|
||||||
if (!effect.active) {
|
if (!effect.active) {
|
||||||
return fn(...args)
|
return fn(...args)
|
||||||
}
|
}
|
||||||
@ -119,11 +123,7 @@ export function resumeTracking() {
|
|||||||
shouldTrack = true
|
shouldTrack = true
|
||||||
}
|
}
|
||||||
|
|
||||||
export function track(
|
export function track(target: object, type: OperationTypes, key?: unknown) {
|
||||||
target: any,
|
|
||||||
type: OperationTypes,
|
|
||||||
key?: string | symbol
|
|
||||||
) {
|
|
||||||
if (!shouldTrack || effectStack.length === 0) {
|
if (!shouldTrack || effectStack.length === 0) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -154,10 +154,10 @@ export function track(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function trigger(
|
export function trigger(
|
||||||
target: any,
|
target: object,
|
||||||
type: OperationTypes,
|
type: OperationTypes,
|
||||||
key?: string | symbol,
|
key?: unknown,
|
||||||
extraInfo?: any
|
extraInfo?: DebuggerEventExtraInfo
|
||||||
) {
|
) {
|
||||||
const depsMap = targetMap.get(target)
|
const depsMap = targetMap.get(target)
|
||||||
if (depsMap === void 0) {
|
if (depsMap === void 0) {
|
||||||
@ -209,23 +209,19 @@ function addRunners(
|
|||||||
|
|
||||||
function scheduleRun(
|
function scheduleRun(
|
||||||
effect: ReactiveEffect,
|
effect: ReactiveEffect,
|
||||||
target: any,
|
target: object,
|
||||||
type: OperationTypes,
|
type: OperationTypes,
|
||||||
key: string | symbol | undefined,
|
key: unknown,
|
||||||
extraInfo: any
|
extraInfo?: DebuggerEventExtraInfo
|
||||||
) {
|
) {
|
||||||
if (__DEV__ && effect.onTrigger) {
|
if (__DEV__ && effect.onTrigger) {
|
||||||
effect.onTrigger(
|
const event: DebuggerEvent = {
|
||||||
extend(
|
|
||||||
{
|
|
||||||
effect,
|
effect,
|
||||||
target,
|
target,
|
||||||
key,
|
key,
|
||||||
type
|
type
|
||||||
},
|
}
|
||||||
extraInfo
|
effect.onTrigger(extraInfo ? extend(event, extraInfo) : event)
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
if (effect.scheduler !== void 0) {
|
if (effect.scheduler !== void 0) {
|
||||||
effect.scheduler(effect)
|
effect.scheduler(effect)
|
||||||
|
@ -13,7 +13,7 @@ import { makeMap } from '@vue/shared'
|
|||||||
// which maintains a Set of subscribers, but we simply store them as
|
// which maintains a Set of subscribers, but we simply store them as
|
||||||
// raw Sets to reduce memory overhead.
|
// raw Sets to reduce memory overhead.
|
||||||
export type Dep = Set<ReactiveEffect>
|
export type Dep = Set<ReactiveEffect>
|
||||||
export type KeyToDepMap = Map<string | symbol, Dep>
|
export type KeyToDepMap = Map<any, Dep>
|
||||||
export const targetMap = new WeakMap<any, KeyToDepMap>()
|
export const targetMap = new WeakMap<any, KeyToDepMap>()
|
||||||
|
|
||||||
// WeakMaps that store {raw <-> observed} pairs.
|
// WeakMaps that store {raw <-> observed} pairs.
|
||||||
@ -83,7 +83,7 @@ export function readonly<T extends object>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function createReactiveObject(
|
function createReactiveObject(
|
||||||
target: any,
|
target: unknown,
|
||||||
toProxy: WeakMap<any, any>,
|
toProxy: WeakMap<any, any>,
|
||||||
toRaw: WeakMap<any, any>,
|
toRaw: WeakMap<any, any>,
|
||||||
baseHandlers: ProxyHandler<any>,
|
baseHandlers: ProxyHandler<any>,
|
||||||
@ -120,11 +120,11 @@ function createReactiveObject(
|
|||||||
return observed
|
return observed
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isReactive(value: any): boolean {
|
export function isReactive(value: unknown): boolean {
|
||||||
return reactiveToRaw.has(value) || readonlyToRaw.has(value)
|
return reactiveToRaw.has(value) || readonlyToRaw.has(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isReadonly(value: any): boolean {
|
export function isReadonly(value: unknown): boolean {
|
||||||
return readonlyToRaw.has(value)
|
return readonlyToRaw.has(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,37 +3,39 @@ import { OperationTypes } from './operations'
|
|||||||
import { isObject } from '@vue/shared'
|
import { isObject } from '@vue/shared'
|
||||||
import { reactive } from './reactive'
|
import { reactive } from './reactive'
|
||||||
import { ComputedRef } from './computed'
|
import { ComputedRef } from './computed'
|
||||||
|
import { CollectionTypes } from './collectionHandlers'
|
||||||
|
|
||||||
export interface Ref<T = any> {
|
export interface Ref<T = any> {
|
||||||
_isRef: true
|
_isRef: true
|
||||||
value: UnwrapRef<T>
|
value: UnwrapRef<T>
|
||||||
}
|
}
|
||||||
|
|
||||||
const convert = (val: any): any => (isObject(val) ? reactive(val) : val)
|
const convert = <T extends unknown>(val: T): T =>
|
||||||
|
isObject(val) ? reactive(val) : val
|
||||||
|
|
||||||
export function ref<T extends Ref>(raw: T): T
|
export function ref<T extends Ref>(raw: T): T
|
||||||
export function ref<T>(raw: T): Ref<T>
|
export function ref<T>(raw: T): Ref<T>
|
||||||
export function ref(raw: any) {
|
export function ref(raw: unknown) {
|
||||||
if (isRef(raw)) {
|
if (isRef(raw)) {
|
||||||
return raw
|
return raw
|
||||||
}
|
}
|
||||||
raw = convert(raw)
|
raw = convert(raw)
|
||||||
const v = {
|
const r = {
|
||||||
_isRef: true,
|
_isRef: true,
|
||||||
get value() {
|
get value() {
|
||||||
track(v, OperationTypes.GET, '')
|
track(r, OperationTypes.GET, '')
|
||||||
return raw
|
return raw
|
||||||
},
|
},
|
||||||
set value(newVal) {
|
set value(newVal) {
|
||||||
raw = convert(newVal)
|
raw = convert(newVal)
|
||||||
trigger(v, OperationTypes.SET, '')
|
trigger(r, OperationTypes.SET, '')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return v as Ref
|
return r as Ref
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isRef(v: any): v is Ref {
|
export function isRef(r: any): r is Ref {
|
||||||
return v ? v._isRef === true : false
|
return r ? r._isRef === true : false
|
||||||
}
|
}
|
||||||
|
|
||||||
export function toRefs<T extends object>(
|
export function toRefs<T extends object>(
|
||||||
@ -61,13 +63,6 @@ function toProxyRef<T extends object, K extends keyof T>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type BailTypes =
|
|
||||||
| Function
|
|
||||||
| Map<any, any>
|
|
||||||
| Set<any>
|
|
||||||
| WeakMap<any, any>
|
|
||||||
| WeakSet<any>
|
|
||||||
|
|
||||||
// Recursively unwraps nested value bindings.
|
// Recursively unwraps nested value bindings.
|
||||||
export type UnwrapRef<T> = {
|
export type UnwrapRef<T> = {
|
||||||
cRef: T extends ComputedRef<infer V> ? UnwrapRef<V> : T
|
cRef: T extends ComputedRef<infer V> ? UnwrapRef<V> : T
|
||||||
@ -80,6 +75,8 @@ export type UnwrapRef<T> = {
|
|||||||
? 'ref'
|
? 'ref'
|
||||||
: T extends Array<any>
|
: T extends Array<any>
|
||||||
? 'array'
|
? 'array'
|
||||||
: T extends BailTypes
|
: T extends Function | CollectionTypes
|
||||||
? 'ref' // bail out on types that shouldn't be unwrapped
|
? 'ref' // bail out on types that shouldn't be unwrapped
|
||||||
: T extends object ? 'object' : 'ref']
|
: T extends object
|
||||||
|
? 'object'
|
||||||
|
: 'ref']
|
||||||
|
@ -77,6 +77,6 @@ export function createComponent<
|
|||||||
}
|
}
|
||||||
|
|
||||||
// implementation, close to no-op
|
// implementation, close to no-op
|
||||||
export function createComponent(options: any) {
|
export function createComponent(options: unknown) {
|
||||||
return isFunction(options) ? { setup: options } : options
|
return isFunction(options) ? { setup: options } : options
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,10 @@ export function provide<T>(key: InjectionKey<T> | string, value: T) {
|
|||||||
|
|
||||||
export function inject<T>(key: InjectionKey<T> | string): T | undefined
|
export function inject<T>(key: InjectionKey<T> | string): T | undefined
|
||||||
export function inject<T>(key: InjectionKey<T> | string, defaultValue: T): T
|
export function inject<T>(key: InjectionKey<T> | string, defaultValue: T): T
|
||||||
export function inject(key: InjectionKey<any> | string, defaultValue?: any) {
|
export function inject(
|
||||||
|
key: InjectionKey<any> | string,
|
||||||
|
defaultValue?: unknown
|
||||||
|
) {
|
||||||
if (currentInstance) {
|
if (currentInstance) {
|
||||||
const provides = currentInstance.provides
|
const provides = currentInstance.provides
|
||||||
if (key in provides) {
|
if (key in provides) {
|
||||||
|
@ -16,7 +16,7 @@ function injectHook(
|
|||||||
target: ComponentInternalInstance | null
|
target: ComponentInternalInstance | null
|
||||||
) {
|
) {
|
||||||
if (target) {
|
if (target) {
|
||||||
;(target[type] || (target[type] = [])).push((...args: any[]) => {
|
;(target[type] || (target[type] = [])).push((...args: unknown[]) => {
|
||||||
if (target.isUnmounted) {
|
if (target.isUnmounted) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ import {
|
|||||||
NOOP
|
NOOP
|
||||||
} from '@vue/shared'
|
} from '@vue/shared'
|
||||||
import { computed } from './apiReactivity'
|
import { computed } from './apiReactivity'
|
||||||
import { watch, WatchOptions, CleanupRegistrator } from './apiWatch'
|
import { watch, WatchOptions, WatchHandler } from './apiWatch'
|
||||||
import { provide, inject } from './apiInject'
|
import { provide, inject } from './apiInject'
|
||||||
import {
|
import {
|
||||||
onBeforeMount,
|
onBeforeMount,
|
||||||
@ -40,7 +40,7 @@ import { Directive } from './directives'
|
|||||||
import { ComponentPublicInstance } from './componentProxy'
|
import { ComponentPublicInstance } from './componentProxy'
|
||||||
import { warn } from './warning'
|
import { warn } from './warning'
|
||||||
|
|
||||||
interface ComponentOptionsBase<
|
export interface ComponentOptionsBase<
|
||||||
Props,
|
Props,
|
||||||
RawBindings,
|
RawBindings,
|
||||||
D,
|
D,
|
||||||
@ -119,12 +119,6 @@ export type ExtractComputedReturns<T extends any> = {
|
|||||||
: ReturnType<T[key]>
|
: ReturnType<T[key]>
|
||||||
}
|
}
|
||||||
|
|
||||||
export type WatchHandler<T = any> = (
|
|
||||||
val: T,
|
|
||||||
oldVal: T,
|
|
||||||
onCleanup: CleanupRegistrator
|
|
||||||
) => any
|
|
||||||
|
|
||||||
type ComponentWatchOptions = Record<
|
type ComponentWatchOptions = Record<
|
||||||
string,
|
string,
|
||||||
string | WatchHandler | { handler: WatchHandler } & WatchOptions
|
string | WatchHandler | { handler: WatchHandler } & WatchOptions
|
||||||
@ -134,7 +128,7 @@ type ComponentInjectOptions =
|
|||||||
| string[]
|
| string[]
|
||||||
| Record<
|
| Record<
|
||||||
string | symbol,
|
string | symbol,
|
||||||
string | symbol | { from: string | symbol; default?: any }
|
string | symbol | { from: string | symbol; default?: unknown }
|
||||||
>
|
>
|
||||||
|
|
||||||
// TODO type inference for these options
|
// TODO type inference for these options
|
||||||
|
@ -21,7 +21,12 @@ import {
|
|||||||
} from './errorHandling'
|
} from './errorHandling'
|
||||||
import { onBeforeUnmount } from './apiLifecycle'
|
import { onBeforeUnmount } from './apiLifecycle'
|
||||||
import { queuePostRenderEffect } from './createRenderer'
|
import { queuePostRenderEffect } from './createRenderer'
|
||||||
import { WatchHandler } from './apiOptions'
|
|
||||||
|
export type WatchHandler<T = any> = (
|
||||||
|
value: T,
|
||||||
|
oldValue: T,
|
||||||
|
onCleanup: CleanupRegistrator
|
||||||
|
) => any
|
||||||
|
|
||||||
export interface WatchOptions {
|
export interface WatchOptions {
|
||||||
lazy?: boolean
|
lazy?: boolean
|
||||||
@ -58,11 +63,7 @@ export function watch<T>(
|
|||||||
// overload #3: array of multiple sources + cb
|
// overload #3: array of multiple sources + cb
|
||||||
export function watch<T extends readonly WatcherSource<unknown>[]>(
|
export function watch<T extends readonly WatcherSource<unknown>[]>(
|
||||||
sources: T,
|
sources: T,
|
||||||
cb: (
|
cb: WatchHandler<MapSources<T>>,
|
||||||
newValues: MapSources<T>,
|
|
||||||
oldValues: MapSources<T>,
|
|
||||||
onCleanup: CleanupRegistrator
|
|
||||||
) => any,
|
|
||||||
options?: WatchOptions
|
options?: WatchOptions
|
||||||
): StopHandle
|
): StopHandle
|
||||||
|
|
||||||
@ -84,9 +85,7 @@ export function watch<T = any>(
|
|||||||
|
|
||||||
function doWatch(
|
function doWatch(
|
||||||
source: WatcherSource | WatcherSource[] | SimpleEffect,
|
source: WatcherSource | WatcherSource[] | SimpleEffect,
|
||||||
cb:
|
cb: WatchHandler | null,
|
||||||
| ((newValue: any, oldValue: any, onCleanup: CleanupRegistrator) => any)
|
|
||||||
| null,
|
|
||||||
{ lazy, deep, flush, onTrack, onTrigger }: WatchOptions = EMPTY_OBJ
|
{ lazy, deep, flush, onTrack, onTrigger }: WatchOptions = EMPTY_OBJ
|
||||||
): StopHandle {
|
): StopHandle {
|
||||||
const instance = currentInstance
|
const instance = currentInstance
|
||||||
@ -95,8 +94,7 @@ function doWatch(
|
|||||||
let getter: () => any
|
let getter: () => any
|
||||||
if (isArray(source)) {
|
if (isArray(source)) {
|
||||||
getter = () =>
|
getter = () =>
|
||||||
source.map(
|
source.map(s =>
|
||||||
s =>
|
|
||||||
isRef(s)
|
isRef(s)
|
||||||
? s.value
|
? s.value
|
||||||
: callWithErrorHandling(s, instance, ErrorCodes.WATCH_GETTER)
|
: callWithErrorHandling(s, instance, ErrorCodes.WATCH_GETTER)
|
||||||
@ -218,7 +216,7 @@ export function instanceWatch(
|
|||||||
return stop
|
return stop
|
||||||
}
|
}
|
||||||
|
|
||||||
function traverse(value: any, seen: Set<any> = new Set()) {
|
function traverse(value: unknown, seen: Set<unknown> = new Set()) {
|
||||||
if (!isObject(value) || seen.has(value)) {
|
if (!isObject(value) || seen.has(value)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ export const enum LifecycleHooks {
|
|||||||
ERROR_CAPTURED = 'ec'
|
ERROR_CAPTURED = 'ec'
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Emit = ((event: string, ...args: unknown[]) => void)
|
export type Emit = (event: string, ...args: unknown[]) => void
|
||||||
|
|
||||||
export interface SetupContext {
|
export interface SetupContext {
|
||||||
attrs: Data
|
attrs: Data
|
||||||
@ -86,13 +86,13 @@ export interface ComponentInternalInstance {
|
|||||||
accessCache: Data | null
|
accessCache: Data | null
|
||||||
// cache for render function values that rely on _ctx but won't need updates
|
// cache for render function values that rely on _ctx but won't need updates
|
||||||
// after initialized (e.g. inline handlers)
|
// after initialized (e.g. inline handlers)
|
||||||
renderCache: any[] | null
|
renderCache: Function[] | null
|
||||||
|
|
||||||
components: Record<string, Component>
|
components: Record<string, Component>
|
||||||
directives: Record<string, Directive>
|
directives: Record<string, Directive>
|
||||||
|
|
||||||
asyncDep: Promise<any> | null
|
asyncDep: Promise<any> | null
|
||||||
asyncResult: any
|
asyncResult: unknown
|
||||||
asyncResolved: boolean
|
asyncResolved: boolean
|
||||||
|
|
||||||
// the rest are only for stateful components
|
// the rest are only for stateful components
|
||||||
|
@ -30,12 +30,12 @@ interface PropOptions<T = any> {
|
|||||||
type?: PropType<T> | true | null
|
type?: PropType<T> | true | null
|
||||||
required?: boolean
|
required?: boolean
|
||||||
default?: T | null | undefined | (() => T | null | undefined)
|
default?: T | null | undefined | (() => T | null | undefined)
|
||||||
validator?(value: any): boolean
|
validator?(value: unknown): boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PropType<T> = PropConstructor<T> | PropConstructor<T>[]
|
export type PropType<T> = PropConstructor<T> | PropConstructor<T>[]
|
||||||
|
|
||||||
type PropConstructor<T> = { new (...args: any[]): T & object } | { (): T }
|
type PropConstructor<T = any> = { new (...args: any[]): T & object } | { (): T }
|
||||||
|
|
||||||
type RequiredKeys<T, MakeDefaultRequired> = {
|
type RequiredKeys<T, MakeDefaultRequired> = {
|
||||||
[K in keyof T]: T[K] extends
|
[K in keyof T]: T[K] extends
|
||||||
@ -56,7 +56,9 @@ type InferPropType<T> = T extends null
|
|||||||
? any // somehow `ObjectConstructor` when inferred from { (): T } becomes `any`
|
? any // somehow `ObjectConstructor` when inferred from { (): T } becomes `any`
|
||||||
: T extends ObjectConstructor | { type: ObjectConstructor }
|
: T extends ObjectConstructor | { type: ObjectConstructor }
|
||||||
? { [key: string]: any }
|
? { [key: string]: any }
|
||||||
: T extends Prop<infer V> ? V : T
|
: T extends Prop<infer V>
|
||||||
|
? V
|
||||||
|
: T
|
||||||
|
|
||||||
export type ExtractPropTypes<
|
export type ExtractPropTypes<
|
||||||
O,
|
O,
|
||||||
@ -96,7 +98,7 @@ type NormalizedPropsOptions = Record<string, NormalizedProp>
|
|||||||
|
|
||||||
export function resolveProps(
|
export function resolveProps(
|
||||||
instance: ComponentInternalInstance,
|
instance: ComponentInternalInstance,
|
||||||
rawProps: any,
|
rawProps: Data | null,
|
||||||
_options: ComponentPropsOptions | void
|
_options: ComponentPropsOptions | void
|
||||||
) {
|
) {
|
||||||
const hasDeclaredProps = _options != null
|
const hasDeclaredProps = _options != null
|
||||||
@ -105,18 +107,18 @@ export function resolveProps(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const props: any = {}
|
const props: Data = {}
|
||||||
let attrs: any = void 0
|
let attrs: Data | undefined = void 0
|
||||||
|
|
||||||
// update the instance propsProxy (passed to setup()) to trigger potential
|
// update the instance propsProxy (passed to setup()) to trigger potential
|
||||||
// changes
|
// changes
|
||||||
const propsProxy = instance.propsProxy
|
const propsProxy = instance.propsProxy
|
||||||
const setProp = propsProxy
|
const setProp = propsProxy
|
||||||
? (key: string, val: any) => {
|
? (key: string, val: unknown) => {
|
||||||
props[key] = val
|
props[key] = val
|
||||||
propsProxy[key] = val
|
propsProxy[key] = val
|
||||||
}
|
}
|
||||||
: (key: string, val: any) => {
|
: (key: string, val: unknown) => {
|
||||||
props[key] = val
|
props[key] = val
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,7 +194,7 @@ export function resolveProps(
|
|||||||
instance.attrs = options
|
instance.attrs = options
|
||||||
? __DEV__ && attrs != null
|
? __DEV__ && attrs != null
|
||||||
? readonly(attrs)
|
? readonly(attrs)
|
||||||
: attrs
|
: attrs!
|
||||||
: instance.props
|
: instance.props
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,8 +281,8 @@ type AssertionResult = {
|
|||||||
|
|
||||||
function validateProp(
|
function validateProp(
|
||||||
name: string,
|
name: string,
|
||||||
value: any,
|
value: unknown,
|
||||||
prop: PropOptions<any>,
|
prop: PropOptions,
|
||||||
isAbsent: boolean
|
isAbsent: boolean
|
||||||
) {
|
) {
|
||||||
const { type, required, validator } = prop
|
const { type, required, validator } = prop
|
||||||
@ -317,7 +319,7 @@ function validateProp(
|
|||||||
|
|
||||||
const simpleCheckRE = /^(String|Number|Boolean|Function|Symbol)$/
|
const simpleCheckRE = /^(String|Number|Boolean|Function|Symbol)$/
|
||||||
|
|
||||||
function assertType(value: any, type: PropConstructor<any>): AssertionResult {
|
function assertType(value: unknown, type: PropConstructor): AssertionResult {
|
||||||
let valid
|
let valid
|
||||||
const expectedType = getType(type)
|
const expectedType = getType(type)
|
||||||
if (simpleCheckRE.test(expectedType)) {
|
if (simpleCheckRE.test(expectedType)) {
|
||||||
@ -342,7 +344,7 @@ function assertType(value: any, type: PropConstructor<any>): AssertionResult {
|
|||||||
|
|
||||||
function getInvalidTypeMessage(
|
function getInvalidTypeMessage(
|
||||||
name: string,
|
name: string,
|
||||||
value: any,
|
value: unknown,
|
||||||
expectedTypes: string[]
|
expectedTypes: string[]
|
||||||
): string {
|
): string {
|
||||||
let message =
|
let message =
|
||||||
@ -368,7 +370,7 @@ function getInvalidTypeMessage(
|
|||||||
return message
|
return message
|
||||||
}
|
}
|
||||||
|
|
||||||
function styleValue(value: any, type: string): string {
|
function styleValue(value: unknown, type: string): string {
|
||||||
if (type === 'String') {
|
if (type === 'String') {
|
||||||
return `"${value}"`
|
return `"${value}"`
|
||||||
} else if (type === 'Number') {
|
} else if (type === 'Number') {
|
||||||
@ -378,7 +380,7 @@ function styleValue(value: any, type: string): string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function toRawType(value: any): string {
|
function toRawType(value: unknown): string {
|
||||||
return toTypeString(value).slice(8, -1)
|
return toTypeString(value).slice(8, -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,12 @@ import { ComponentInternalInstance, Data, Emit } from './component'
|
|||||||
import { nextTick } from './scheduler'
|
import { nextTick } from './scheduler'
|
||||||
import { instanceWatch } from './apiWatch'
|
import { instanceWatch } from './apiWatch'
|
||||||
import { EMPTY_OBJ, hasOwn, isGloballyWhitelisted } from '@vue/shared'
|
import { EMPTY_OBJ, hasOwn, isGloballyWhitelisted } from '@vue/shared'
|
||||||
import { ExtractComputedReturns } from './apiOptions'
|
import {
|
||||||
|
ExtractComputedReturns,
|
||||||
|
ComponentOptionsBase,
|
||||||
|
ComputedOptions,
|
||||||
|
MethodOptions
|
||||||
|
} from './apiOptions'
|
||||||
import { UnwrapRef, ReactiveEffect } from '@vue/reactivity'
|
import { UnwrapRef, ReactiveEffect } from '@vue/reactivity'
|
||||||
import { warn } from './warning'
|
import { warn } from './warning'
|
||||||
|
|
||||||
@ -12,8 +17,8 @@ export type ComponentPublicInstance<
|
|||||||
P = {},
|
P = {},
|
||||||
B = {},
|
B = {},
|
||||||
D = {},
|
D = {},
|
||||||
C = {},
|
C extends ComputedOptions = {},
|
||||||
M = {},
|
M extends MethodOptions = {},
|
||||||
PublicProps = P
|
PublicProps = P
|
||||||
> = {
|
> = {
|
||||||
[key: string]: any
|
[key: string]: any
|
||||||
@ -26,7 +31,7 @@ export type ComponentPublicInstance<
|
|||||||
$parent: ComponentInternalInstance | null
|
$parent: ComponentInternalInstance | null
|
||||||
$emit: Emit
|
$emit: Emit
|
||||||
$el: any
|
$el: any
|
||||||
$options: any
|
$options: ComponentOptionsBase<P, B, D, C, M>
|
||||||
$forceUpdate: ReactiveEffect
|
$forceUpdate: ReactiveEffect
|
||||||
$nextTick: typeof nextTick
|
$nextTick: typeof nextTick
|
||||||
$watch: typeof instanceWatch
|
$watch: typeof instanceWatch
|
||||||
@ -134,7 +139,10 @@ export const PublicInstanceProxyHandlers: ProxyHandler<any> = {
|
|||||||
if (__RUNTIME_COMPILE__) {
|
if (__RUNTIME_COMPILE__) {
|
||||||
// this trap is only called in browser-compiled render functions that use
|
// this trap is only called in browser-compiled render functions that use
|
||||||
// `with (this) {}`
|
// `with (this) {}`
|
||||||
PublicInstanceProxyHandlers.has = (_: any, key: string): boolean => {
|
PublicInstanceProxyHandlers.has = (
|
||||||
|
_: ComponentInternalInstance,
|
||||||
|
key: string
|
||||||
|
): boolean => {
|
||||||
return key[0] !== '_' && !isGloballyWhitelisted(key)
|
return key[0] !== '_' && !isGloballyWhitelisted(key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,8 @@ import {
|
|||||||
createComponentInstance,
|
createComponentInstance,
|
||||||
setupStatefulComponent,
|
setupStatefulComponent,
|
||||||
handleSetupResult,
|
handleSetupResult,
|
||||||
Component
|
Component,
|
||||||
|
Data
|
||||||
} from './component'
|
} from './component'
|
||||||
import {
|
import {
|
||||||
renderComponentRoot,
|
renderComponentRoot,
|
||||||
@ -36,7 +37,8 @@ import {
|
|||||||
ReactiveEffectOptions,
|
ReactiveEffectOptions,
|
||||||
isRef,
|
isRef,
|
||||||
Ref,
|
Ref,
|
||||||
toRaw
|
toRaw,
|
||||||
|
DebuggerEvent
|
||||||
} from '@vue/reactivity'
|
} from '@vue/reactivity'
|
||||||
import { resolveProps } from './componentProps'
|
import { resolveProps } from './componentProps'
|
||||||
import { resolveSlots } from './componentSlots'
|
import { resolveSlots } from './componentSlots'
|
||||||
@ -70,7 +72,7 @@ function isSameType(n1: VNode, n2: VNode): boolean {
|
|||||||
return n1.type === n2.type && n1.key === n2.key
|
return n1.type === n2.type && n1.key === n2.key
|
||||||
}
|
}
|
||||||
|
|
||||||
function invokeHooks(hooks: Function[], arg?: any) {
|
function invokeHooks(hooks: Function[], arg?: DebuggerEvent) {
|
||||||
for (let i = 0; i < hooks.length; i++) {
|
for (let i = 0; i < hooks.length; i++) {
|
||||||
hooks[i](arg)
|
hooks[i](arg)
|
||||||
}
|
}
|
||||||
@ -555,8 +557,8 @@ export function createRenderer<
|
|||||||
function patchProps(
|
function patchProps(
|
||||||
el: HostElement,
|
el: HostElement,
|
||||||
vnode: HostVNode,
|
vnode: HostVNode,
|
||||||
oldProps: any,
|
oldProps: Data,
|
||||||
newProps: any,
|
newProps: Data,
|
||||||
parentComponent: ComponentInternalInstance | null,
|
parentComponent: ComponentInternalInstance | null,
|
||||||
parentSuspense: HostSuspenseBoundary | null,
|
parentSuspense: HostSuspenseBoundary | null,
|
||||||
isSVG: boolean
|
isSVG: boolean
|
||||||
@ -1160,14 +1162,23 @@ export function createRenderer<
|
|||||||
) {
|
) {
|
||||||
// create reactive effect for rendering
|
// create reactive effect for rendering
|
||||||
let mounted = false
|
let mounted = false
|
||||||
instance.update = effect(function componentEffect() {
|
instance.update = effect(
|
||||||
|
function componentEffect() {
|
||||||
if (!mounted) {
|
if (!mounted) {
|
||||||
const subTree = (instance.subTree = renderComponentRoot(instance))
|
const subTree = (instance.subTree = renderComponentRoot(instance))
|
||||||
// beforeMount hook
|
// beforeMount hook
|
||||||
if (instance.bm !== null) {
|
if (instance.bm !== null) {
|
||||||
invokeHooks(instance.bm)
|
invokeHooks(instance.bm)
|
||||||
}
|
}
|
||||||
patch(null, subTree, container, anchor, instance, parentSuspense, isSVG)
|
patch(
|
||||||
|
null,
|
||||||
|
subTree,
|
||||||
|
container,
|
||||||
|
anchor,
|
||||||
|
instance,
|
||||||
|
parentSuspense,
|
||||||
|
isSVG
|
||||||
|
)
|
||||||
initialVNode.el = subTree.el
|
initialVNode.el = subTree.el
|
||||||
// mounted hook
|
// mounted hook
|
||||||
if (instance.m !== null) {
|
if (instance.m !== null) {
|
||||||
@ -1225,7 +1236,9 @@ export function createRenderer<
|
|||||||
popWarningContext()
|
popWarningContext()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, __DEV__ ? createDevEffectOptions(instance) : prodEffectOptions)
|
},
|
||||||
|
__DEV__ ? createDevEffectOptions(instance) : prodEffectOptions
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateComponentPreRender(
|
function updateComponentPreRender(
|
||||||
|
@ -65,7 +65,7 @@ function applyDirective(
|
|||||||
props: Record<any, any>,
|
props: Record<any, any>,
|
||||||
instance: ComponentInternalInstance,
|
instance: ComponentInternalInstance,
|
||||||
directive: Directive,
|
directive: Directive,
|
||||||
value?: any,
|
value?: unknown,
|
||||||
arg?: string,
|
arg?: string,
|
||||||
modifiers: DirectiveModifiers = EMPTY_OBJ
|
modifiers: DirectiveModifiers = EMPTY_OBJ
|
||||||
) {
|
) {
|
||||||
|
@ -54,9 +54,9 @@ export function callWithErrorHandling(
|
|||||||
fn: Function,
|
fn: Function,
|
||||||
instance: ComponentInternalInstance | null,
|
instance: ComponentInternalInstance | null,
|
||||||
type: ErrorTypes,
|
type: ErrorTypes,
|
||||||
args?: any[]
|
args?: unknown[]
|
||||||
) {
|
) {
|
||||||
let res: any
|
let res
|
||||||
try {
|
try {
|
||||||
res = args ? fn(...args) : fn()
|
res = args ? fn(...args) : fn()
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -69,7 +69,7 @@ export function callWithAsyncErrorHandling(
|
|||||||
fn: Function | Function[],
|
fn: Function | Function[],
|
||||||
instance: ComponentInternalInstance | null,
|
instance: ComponentInternalInstance | null,
|
||||||
type: ErrorTypes,
|
type: ErrorTypes,
|
||||||
args?: any[]
|
args?: unknown[]
|
||||||
) {
|
) {
|
||||||
if (isFunction(fn)) {
|
if (isFunction(fn)) {
|
||||||
const res = callWithErrorHandling(fn, instance, type, args)
|
const res = callWithErrorHandling(fn, instance, type, args)
|
||||||
|
@ -2,8 +2,12 @@ import { VNodeChild } from '../vnode'
|
|||||||
import { isArray, isString, isObject } from '@vue/shared'
|
import { isArray, isString, isObject } from '@vue/shared'
|
||||||
|
|
||||||
export function renderList(
|
export function renderList(
|
||||||
source: any,
|
source: unknown,
|
||||||
renderItem: (value: any, key: string | number, index?: number) => VNodeChild
|
renderItem: (
|
||||||
|
value: unknown,
|
||||||
|
key: string | number,
|
||||||
|
index?: number
|
||||||
|
) => VNodeChild
|
||||||
): VNodeChild[] {
|
): VNodeChild[] {
|
||||||
let ret: VNodeChild[]
|
let ret: VNodeChild[]
|
||||||
if (isArray(source) || isString(source)) {
|
if (isArray(source) || isString(source)) {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { Data } from '../component'
|
||||||
import { Slot } from '../componentSlots'
|
import { Slot } from '../componentSlots'
|
||||||
import {
|
import {
|
||||||
VNodeChildren,
|
VNodeChildren,
|
||||||
@ -11,7 +12,7 @@ import { PatchFlags } from '@vue/shared'
|
|||||||
export function renderSlot(
|
export function renderSlot(
|
||||||
slots: Record<string, Slot>,
|
slots: Record<string, Slot>,
|
||||||
name: string,
|
name: string,
|
||||||
props: any = {},
|
props: Data = {},
|
||||||
// this is not a user-facing function, so the fallback is always generated by
|
// this is not a user-facing function, so the fallback is always generated by
|
||||||
// the compiler and guaranteed to be an array
|
// the compiler and guaranteed to be an array
|
||||||
fallback?: VNodeChildren
|
fallback?: VNodeChildren
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { isArray, isPlainObject, objectToString } from '@vue/shared'
|
import { isArray, isPlainObject, objectToString } from '@vue/shared'
|
||||||
|
|
||||||
// for converting {{ interpolation }} values to displayed strings.
|
// for converting {{ interpolation }} values to displayed strings.
|
||||||
export function toString(val: any): string {
|
export function toString(val: unknown): string {
|
||||||
return val == null
|
return val == null
|
||||||
? ''
|
? ''
|
||||||
: isArray(val) || (isPlainObject(val) && val.toString === objectToString)
|
: isArray(val) || (isPlainObject(val) && val.toString === objectToString)
|
||||||
|
@ -117,7 +117,7 @@ export function patchEvent(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function createInvoker(
|
function createInvoker(
|
||||||
initialValue: any,
|
initialValue: EventValue,
|
||||||
instance: ComponentInternalInstance | null
|
instance: ComponentInternalInstance | null
|
||||||
) {
|
) {
|
||||||
const invoker: Invoker = (e: Event) => {
|
const invoker: Invoker = (e: Event) => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user