new <P extends object = {}, D extends object = {}>(): MergedComponent<P, D>
}
-export type MergedComponent<P, D> = D & P & MountedComponent<P, D>
+export type MergedComponent<P, D> = D & P & ComponentInstance<P, D>
export interface FunctionalComponent<P = {}> {
(props: Readonly<P>, slots: Slots, attrs: Data): any
// this interface is merged with the class type
// to represent a mounted component
-export interface MountedComponent<P = {}, D = {}> extends InternalComponent {
+export interface ComponentInstance<P = {}, D = {}> extends InternalComponent {
$vnode: MountedVNode
$data: D
$props: Readonly<P>
$attrs: Data
$computed: Data
$slots: Slots
- $root: MountedComponent
- $children: MountedComponent[]
+ $root: ComponentInstance
+ $children: ComponentInstance[]
$options: ComponentOptions<P, D>
data?(): Partial<D>
errorCaptured?(): (
err: Error,
type: ErrorTypes,
- target: MountedComponent
+ target: ComponentInstance
) => boolean | void
activated?(): void
deactivated?(): void
$forceUpdate: () => void
$nextTick: (fn: () => void) => Promise<any>
- _self: MountedComponent<D, P> // on proxies only
+ _self: ComponentInstance<D, P> // on proxies only
}
class InternalComponent {
public $attrs: Data | null = null
public $computed: Data | null = null
public $slots: Slots | null = null
- public $root: MountedComponent | null = null
- public $parent: MountedComponent | null = null
- public $children: MountedComponent[] = []
+ public $root: ComponentInstance | null = null
+ public $parent: ComponentInstance | null = null
+ public $children: ComponentInstance[] = []
public $options: any
- public $refs: Record<string, MountedComponent | RenderNode> = {}
+ public $refs: Record<string, ComponentInstance | RenderNode> = {}
public $proxy: any = null
public $forceUpdate: (() => void) | null = null
}
$watch(
- keyOrFn: string | (() => any),
- cb: (newValue: any, oldValue: any) => void,
+ keyOrFn: string | ((this: this) => any),
+ cb: (this: this, newValue: any, oldValue: any) => void,
options?: WatchOptions
- ) {
+ ): () => void {
return setupWatcher(this as any, keyOrFn, cb, options)
}
import { EMPTY_OBJ } from './utils'
import { computed, stop, ComputedGetter } from '@vue/observer'
-import { ComponentClass, MountedComponent } from './component'
+import { ComponentClass, ComponentInstance } from './component'
import { ComponentComputedOptions } from './componentOptions'
const extractionCache: WeakMap<
}
export function initializeComputed(
- instance: MountedComponent,
+ instance: ComponentInstance,
computedOptions: ComponentComputedOptions | undefined
) {
if (!computedOptions) {
)
}
-export function teardownComputed(instance: MountedComponent) {
+export function teardownComputed(instance: ComponentInstance) {
const handles = instance._computedGetters
if (handles !== null) {
for (const key in handles) {
-import { MergedComponent, MountedComponent } from './component'
+import { MergedComponent, ComponentInstance } from './component'
import { Slots } from './vdom'
export type Data = Record<string, any>
validator?(value: T): boolean
}
-export interface ComponentComputedOptions<This = MountedComponent> {
+export interface ComponentComputedOptions<This = ComponentInstance> {
[key: string]: (this: This, c: any) => any
}
-export interface ComponentWatchOptions<This = MountedComponent> {
+export interface ComponentWatchOptions<This = ComponentInstance> {
[key: string]: ComponentWatchOption<This>
}
-export type ComponentWatchOption<This = MountedComponent> =
+export type ComponentWatchOption<This = ComponentInstance> =
| WatchHandler<This>
| WatchHandler<This>[]
| WatchOptionsWithHandler<This>
import { immutable, unwrap, lock, unlock } from '@vue/observer'
-import { MountedComponent } from './component'
+import { ComponentInstance } from './component'
import {
Data,
ComponentPropsOptions,
capitalize
} from './utils'
-export function initializeProps(instance: MountedComponent, data: Data | null) {
+export function initializeProps(
+ instance: ComponentInstance,
+ data: Data | null
+) {
const { props, attrs } = resolveProps(data, instance.$options.props)
instance.$props = immutable(props || {})
instance.$attrs = immutable(attrs || {})
}
-export function updateProps(instance: MountedComponent, nextData: Data) {
+export function updateProps(instance: ComponentInstance, nextData: Data) {
// instance.$props and instance.$attrs are observables that should not be
// replaced. Instead, we mutate them to match latest props, which will trigger
// updates if any value that's been used in child component has changed.
-import { MountedComponent } from './component'
+import { ComponentInstance } from './component'
const bindCache = new WeakMap()
}
const renderProxyHandlers = {
- get(target: MountedComponent<any, any>, key: string, receiver: any) {
+ get(target: ComponentInstance<any, any>, key: string, receiver: any) {
if (key === '_self') {
return target
} else if (
}
},
set(
- target: MountedComponent<any, any>,
+ target: ComponentInstance<any, any>,
key: string,
value: any,
receiver: any
}
}
-export function createRenderProxy(instance: any): MountedComponent {
- return new Proxy(instance, renderProxyHandlers) as MountedComponent
+export function createRenderProxy(instance: any): ComponentInstance {
+ return new Proxy(instance, renderProxyHandlers) as ComponentInstance
}
import { EMPTY_OBJ } from './utils'
-import { MountedComponent } from './component'
+import { ComponentInstance } from './component'
import { observable } from '@vue/observer'
-export function initializeState(instance: MountedComponent) {
+export function initializeState(instance: ComponentInstance) {
if (instance.data) {
instance._rawData = instance.data()
instance.$data = observable(instance._rawData)
import { EMPTY_OBJ } from './utils'
import { h } from './h'
import { VNode, MountedVNode, createFragment } from './vdom'
-import { Component, MountedComponent, ComponentClass } from './component'
+import { Component, ComponentInstance, ComponentClass } from './component'
import { createTextVNode, cloneVNode } from './vdom'
import { initializeState } from './componentState'
import { initializeProps } from './componentProps'
teardownComputed
} from './componentComputed'
import { initializeWatch, teardownWatch } from './componentWatch'
-import { Data, ComponentOptions } from './componentOptions'
+import { ComponentOptions } from './componentOptions'
import { createRenderProxy } from './componentProxy'
import { handleError, ErrorTypes } from './errorHandling'
export function createComponentInstance(
vnode: VNode,
Component: ComponentClass,
- parentComponent: MountedComponent | null
-): MountedComponent {
- const instance = (vnode.children = new Component()) as MountedComponent
+ parentComponent: ComponentInstance | null
+): ComponentInstance {
+ const instance = (vnode.children = new Component()) as ComponentInstance
instance.$parentVNode = vnode as MountedVNode
// renderProxy
instance.created.call(proxy)
}
- return instance as MountedComponent
+ return instance as ComponentInstance
}
-export function renderInstanceRoot(instance: MountedComponent): VNode {
+export function renderInstanceRoot(instance: ComponentInstance): VNode {
let vnode
try {
vnode = instance.render.call(instance.$proxy, h, {
)
}
-export function teardownComponentInstance(instance: MountedComponent) {
+export function teardownComponentInstance(instance: ComponentInstance) {
if (instance._unmounted) {
return
}
export function normalizeComponentRoot(
vnode: any,
componentVNode: VNode | null,
- attrs: Data | void,
+ attrs: Record<string, any> | void,
inheritAttrs: boolean | void
): VNode {
if (vnode == null) {
}
export function shouldUpdateFunctionalComponent(
- prevProps: Data | null,
- nextProps: Data | null
+ prevProps: Record<string, any> | null,
+ nextProps: Record<string, any> | null
): boolean {
if (prevProps === nextProps) {
return false
export function createComponentClassFromOptions(
options: ComponentOptions
): ComponentClass {
- class ObjectComponent extends Component {
+ class AnonymousComponent extends Component {
constructor() {
super()
this.$options = options
}
}
+ const proto = AnonymousComponent.prototype as any
for (const key in options) {
const value = options[key]
+ // name -> displayName
+ if (__COMPAT__ && key === 'name') {
+ options.displayName = options.name
+ }
if (typeof value === 'function') {
- ;(ObjectComponent.prototype as any)[key] =
- key === 'render'
- ? function() {
- return value.call(this, h)
- }
- : value
+ if (__COMPAT__ && key === 'render') {
+ proto[key] = function() {
+ return value.call(this, h)
+ }
+ } else {
+ proto[key] = value
+ }
}
if (key === 'computed') {
const isGet = typeof value === 'function'
- Object.defineProperty(ObjectComponent.prototype, key, {
+ Object.defineProperty(proto, key, {
configurable: true,
get: isGet ? value : value.get,
set: isGet ? undefined : value.set
}
if (key === 'methods') {
for (const method in value) {
- ;(ObjectComponent.prototype as any)[method] = value[method]
+ if (__DEV__ && proto.hasOwnProperty(method)) {
+ console.warn(
+ `Object syntax contains method name that conflicts with ` +
+ `lifecycle hook: "${method}"`
+ )
+ }
+ proto[method] = value[method]
}
}
}
- return ObjectComponent as ComponentClass
+ return AnonymousComponent as ComponentClass
}
import { EMPTY_OBJ, NOOP } from './utils'
-import { MountedComponent } from './component'
+import { ComponentInstance } from './component'
import { ComponentWatchOptions, WatchOptions } from './componentOptions'
import { autorun, stop } from '@vue/observer'
import { queueJob } from '@vue/scheduler'
import { handleError, ErrorTypes } from './errorHandling'
export function initializeWatch(
- instance: MountedComponent,
+ instance: ComponentInstance,
options: ComponentWatchOptions | undefined
) {
if (options !== void 0) {
}
export function setupWatcher(
- instance: MountedComponent,
+ instance: ComponentInstance,
keyOrFn: string | Function,
cb: (newValue: any, oldValue: any) => void,
options: WatchOptions = EMPTY_OBJ as WatchOptions
}
}
-export function teardownWatch(instance: MountedComponent) {
+export function teardownWatch(instance: ComponentInstance) {
if (instance._watchHandles !== null) {
instance._watchHandles.forEach(stop)
}
VNodeChildren
} from './vdom'
import {
- MountedComponent,
+ ComponentInstance,
FunctionalComponent,
ComponentClass
} from './component'
function mount(
vnode: VNode,
container: RenderNode | null,
- parentComponent: MountedComponent | null,
+ parentComponent: ComponentInstance | null,
isSVG: boolean,
endNode: RenderNode | null
) {
function mountArrayChildren(
children: VNode[],
container: RenderNode | null,
- parentComponent: MountedComponent | null,
+ parentComponent: ComponentInstance | null,
isSVG: boolean,
endNode: RenderNode | null
) {
function mountElement(
vnode: VNode,
container: RenderNode | null,
- parentComponent: MountedComponent | null,
+ parentComponent: ComponentInstance | null,
isSVG: boolean,
endNode: RenderNode | null
) {
}
}
- function mountRef(ref: Ref, el: RenderNode | MountedComponent) {
+ function mountRef(ref: Ref, el: RenderNode | ComponentInstance) {
lifecycleHooks.push(() => {
ref(el)
})
function mountStatefulComponent(
vnode: VNode,
container: RenderNode | null,
- parentComponent: MountedComponent | null,
+ parentComponent: ComponentInstance | null,
isSVG: boolean,
endNode: RenderNode | null
) {
function mountFunctionalComponent(
vnode: VNode,
container: RenderNode | null,
- parentComponent: MountedComponent | null,
+ parentComponent: ComponentInstance | null,
isSVG: boolean,
endNode: RenderNode | null
) {
function mountFragment(
vnode: VNode,
container: RenderNode | null,
- parentComponent: MountedComponent | null,
+ parentComponent: ComponentInstance | null,
isSVG: boolean,
endNode: RenderNode | null
) {
function mountPortal(
vnode: VNode,
container: RenderNode | null,
- parentComponent: MountedComponent | null
+ parentComponent: ComponentInstance | null
) {
const { tag, children, childFlags, ref } = vnode
const target = typeof tag === 'string' ? platformQuerySelector(tag) : tag
prevVNode: MountedVNode,
nextVNode: VNode,
container: RenderNode,
- parentComponent: MountedComponent | null,
+ parentComponent: ComponentInstance | null,
isSVG: boolean
) {
const nextFlags = nextVNode.flags
prevVNode: MountedVNode,
nextVNode: VNode,
container: RenderNode,
- parentComponent: MountedComponent | null,
+ parentComponent: ComponentInstance | null,
isSVG: boolean
) {
const { flags, tag } = nextVNode
prevVNode: MountedVNode,
nextVNode: VNode,
container: RenderNode,
- parentComponent: MountedComponent | null,
+ parentComponent: ComponentInstance | null,
isSVG: boolean
) {
const { tag, flags } = nextVNode
} = nextVNode
const instance = (nextVNode.children =
- prevVNode.children) as MountedComponent
+ prevVNode.children) as ComponentInstance
instance.$slots = nextSlots || EMPTY_OBJ
instance.$parentVNode = nextVNode as MountedVNode
prevVNode: MountedVNode,
nextVNode: VNode,
container: RenderNode,
- parentComponent: MountedComponent | null,
+ parentComponent: ComponentInstance | null,
isSVG: boolean
) {
// functional component tree is stored on the vnode as `children`
prevVNode: MountedVNode,
nextVNode: VNode,
container: RenderNode,
- parentComponent: MountedComponent | null,
+ parentComponent: ComponentInstance | null,
isSVG: boolean
) {
// determine the tail node of the previous fragment,
function patchPortal(
prevVNode: MountedVNode,
nextVNode: VNode,
- parentComponent: MountedComponent | null
+ parentComponent: ComponentInstance | null
) {
const prevContainer = prevVNode.tag as RenderNode
const nextContainer = nextVNode.tag as RenderNode
prevVNode: MountedVNode,
nextVNode: VNode,
container: RenderNode,
- parentComponent: MountedComponent | null,
+ parentComponent: ComponentInstance | null,
isSVG: boolean
) {
const refNode = platformNextSibling(getVNodeLastEl(prevVNode))
prevChildren: VNodeChildren,
nextChildren: VNodeChildren,
container: RenderNode,
- parentComponent: MountedComponent | null,
+ parentComponent: ComponentInstance | null,
isSVG: boolean,
endNode: RenderNode | null
) {
container: RenderNode,
prevLength: number,
nextLength: number,
- parentComponent: MountedComponent | null,
+ parentComponent: ComponentInstance | null,
isSVG: boolean,
endNode: RenderNode | null
) {
container: RenderNode,
prevLength: number,
nextLength: number,
- parentComponent: MountedComponent | null,
+ parentComponent: ComponentInstance | null,
isSVG: boolean,
endNode: RenderNode | null
) {
} else if (flags & VNodeFlags.COMPONENT) {
if (flags & VNodeFlags.COMPONENT_STATEFUL) {
if (flags & VNodeFlags.COMPONENT_STATEFUL_SHOULD_KEEP_ALIVE) {
- deactivateComponentInstance(children as MountedComponent)
+ deactivateComponentInstance(children as ComponentInstance)
} else {
- unmountComponentInstance(children as MountedComponent)
+ unmountComponentInstance(children as ComponentInstance)
}
} else {
unmount(children as MountedVNode)
parentVNode: VNode,
Component: ComponentClass,
container: RenderNode | null,
- parentComponent: MountedComponent | null,
+ parentComponent: ComponentInstance | null,
isSVG: boolean,
endNode: RenderNode | null
): RenderNode {
// a vnode may already have an instance if this is a compat call with
// new Vue()
const instance =
- (__COMPAT__ && (parentVNode.children as MountedComponent)) ||
+ (__COMPAT__ && (parentVNode.children as ComponentInstance)) ||
createComponentInstance(parentVNode, Component, parentComponent)
// inject platform-specific unmount to keep-alive container
}
function mountComponentInstanceCallbacks(
- instance: MountedComponent,
+ instance: ComponentInstance,
ref: Ref | null
) {
if (ref) {
}
}
- function updateComponentInstance(instance: MountedComponent, isSVG: boolean) {
+ function updateComponentInstance(
+ instance: ComponentInstance,
+ isSVG: boolean
+ ) {
const prevVNode = instance.$vnode
if (instance.beforeUpdate) {
}
}
- function unmountComponentInstance(instance: MountedComponent) {
+ function unmountComponentInstance(instance: ComponentInstance) {
if (instance._unmounted) {
return
}
// Keep Alive ----------------------------------------------------------------
function activateComponentInstance(vnode: VNode) {
- const instance = vnode.children as MountedComponent
+ const instance = vnode.children as ComponentInstance
vnode.el = instance.$el
lifecycleHooks.push(() => {
callActivatedHook(instance, true)
})
}
- function callActivatedHook(instance: MountedComponent, asRoot: boolean) {
+ function callActivatedHook(instance: ComponentInstance, asRoot: boolean) {
// 1. check if we are inside an inactive parent tree.
if (asRoot) {
instance._inactiveRoot = false
}
}
- function deactivateComponentInstance(instance: MountedComponent) {
+ function deactivateComponentInstance(instance: ComponentInstance) {
callDeactivateHook(instance, true)
}
- function callDeactivateHook(instance: MountedComponent, asRoot: boolean) {
+ function callDeactivateHook(instance: ComponentInstance, asRoot: boolean) {
if (asRoot) {
instance._inactiveRoot = true
if (isInInactiveTree(instance)) return
}
}
- function isInInactiveTree(instance: MountedComponent): boolean {
+ function isInInactiveTree(instance: ComponentInstance): boolean {
while ((instance = instance.$parent as any) !== null) {
if (instance._inactiveRoot) return true
}
}
flushHooks()
return vnode && vnode.flags & VNodeFlags.COMPONENT_STATEFUL
- ? (vnode.children as MountedComponent).$proxy
+ ? (vnode.children as ComponentInstance).$proxy
: null
}
-import { MountedComponent } from './component'
+import { ComponentInstance } from './component'
export const enum ErrorTypes {
BEFORE_CREATE = 1,
export function handleError(
err: Error,
- instance: MountedComponent,
+ instance: ComponentInstance,
type: ErrorTypes
) {
let cur = instance
import { VNode } from '../vdom'
-import { MountedComponent } from '../component'
+import { ComponentInstance } from '../component'
interface DirectiveBinding {
- instance: MountedComponent
+ instance: ComponentInstance
value?: any
oldValue?: any
arg?: string
export function applyDirective(
vnode: VNode,
directive: Directive,
- instance: MountedComponent,
+ instance: ComponentInstance,
value?: any,
arg?: string,
modifiers?: DirectiveModifiers
-import { Component, ComponentClass, MountedComponent } from '../component'
+import { Component, ComponentClass, ComponentInstance } from '../component'
import { VNode, Slots, cloneVNode } from '../vdom'
import { VNodeFlags } from '../flags'
keys: Set<CacheKey> = new Set()
// to be set in createRenderer when instance is created
- $unmount: (instance: MountedComponent) => void
+ $unmount: (instance: ComponentInstance) => void
beforeUnmount() {
this.cache.forEach(vnode => {
// change flag so it can be properly unmounted
vnode.flags = VNodeFlags.COMPONENT_STATEFUL_NORMAL
- this.$unmount(vnode.children as MountedComponent)
+ this.$unmount(vnode.children as ComponentInstance)
})
}
const cached = this.cache.get(key) as VNode
const current = this.$vnode
if (!current || cached.tag !== current.tag) {
- this.$unmount(cached.children as MountedComponent)
+ this.$unmount(cached.children as ComponentInstance)
}
this.cache.delete(key)
this.keys.delete(key)
import {
- MountedComponent,
+ ComponentInstance,
ComponentClass,
FunctionalComponent
} from './component'
export type VNodeChildren =
| VNode[] // ELEMENT | PORTAL
- | MountedComponent // COMPONENT_STATEFUL
+ | ComponentInstance // COMPONENT_STATEFUL
| VNode // COMPONENT_FUNCTIONAL
| string // TEXT
| null
export type Key = string | number
-export type Ref = (t: RenderNode | MountedComponent | null) => void
+export type Ref = (t: RenderNode | ComponentInstance | null) => void
export type Slot = (...args: any[]) => VNode[]