Vue3系列 - 组件实例与当前实例
组件实例与当前实例
Vue3的组合式API依赖于当前组件实例的概念,通过currentInstance变量跟踪当前正在执行的组件实例。这对于在setup函数中使用生命周期钩子、依赖注入等功能至关重要。让我们深入了解Vue2.7中组件实例与当前实例的实现。
currentInstance变量
currentInstance是一个全局变量,用于跟踪当前正在执行的组件实例:
// 在currentInstance.ts中
export let currentInstance = null
export function setCurrentInstance(vm = null) {
currentInstance = vm
}
export function getCurrentInstance() {
return {
proxy: currentInstance
}
}在setup中设置当前实例
在执行setup函数时,会设置当前实例:
export function initSetup(vm) {
// ...
if (setup) {
// ...
setCurrentInstance(vm)
pushTarget()
const setupResult = invokeWithErrorHandling(
setup,
null,
[vm._props || shallowReactive({}), ctx],
vm,
`setup`
)
popTarget()
setCurrentInstance()
// ...
}
}setCurrentInstance(vm)设置当前实例为vm,setCurrentInstance()(不带参数)将当前实例重置为null。
在生命周期钩子中使用当前实例
生命周期钩子函数使用当前实例来注入钩子:
function createLifeCycle(hookName) {
return (fn, target = currentInstance) => {
if (!target) {
__DEV__ &&
warn(
`${formatName(hookName)} is called when there is no active component instance to be ` +
`associated with. ` +
`Lifecycle injection APIs can only be used during execution of setup().`
)
return
}
return injectHook(target, hookName, fn)
}
}如果没有当前实例(即不在setup函数中调用),则会在开发环境中发出警告。
在依赖注入中使用当前实例
依赖注入(provide/inject)也依赖于当前实例:
export function provide(key, value) {
if (!currentInstance) {
// 警告...
} else {
// 在当前实例上提供值...
}
}
export function inject(key, defaultValue) {
if (!currentInstance) {
// 警告...
} else {
// 从祖先组件获取注入的值...
}
}getCurrentInstance API
Vue2.7也提供了getCurrentInstance API,允许在setup函数中获取当前组件实例:
export function getCurrentInstance() {
return {
proxy: currentInstance
}
}这个API主要用于高级用例和库开发,一般应用开发中应该避免直接使用组件实例。
组件实例的结构
Vue2.7中的组件实例(Component类)包含了组件的所有信息和方法:
export declare class Component {
constructor(options?: any)
// 构造信息
static cid: number
static options: Record<string, any>
// 扩展
static extend: GlobalAPI['extend']
// ...
// 公共属性
$el: any
$data: Record<string, any>
$props: Record<string, any>
$options: ComponentOptions
$parent: Component | undefined
$root: Component
$children: Array<Component>
$refs: {
[key: string]: Component | Element | Array<Component | Element> | undefined
}
$slots: { [key: string]: Array<VNode> }
// ...
}总结
组件实例与当前实例的概念是Vue组合式API的基础。通过currentInstance变量,Vue能够在setup函数中提供生命周期钩子、依赖注入等功能。理解组件实例与当前实例的实现原理,有助于我们更好地使用组合式API,解决组件实例相关的问题。