Skip to content

父组件与子组件的理解

假设如下场景

父组件是 ParentComp,绑定的服务是 ParentService。

父组件下依赖的子组件有 ChildComp1、ChildComp2、ChildComp3...,对应的服务有 ChildService1、ChildService2、ChildService3...

父组件明确指定子组件

一般情况下,父组件需要依赖哪些子组件是明确的,因为可以从 template 中明确知道使用了哪些子组件。

特殊情况是使用了 slot 传递子组件,这时候子组件就是不确定的。

当然这里的不确定是指定义父组件阶段,等到父组件实例化阶段,slot 对应的子组件又是明确的了。

子组件不确定父组件

子组件不确定父组件是显然的,因为子组件是可以在多个不同的父组件中使用的,既然可以存在任意数量的父组件,那么显然父组件就是不确定的。

当然这里的不确定是指定义子组件阶段,等到子组件实例化阶段,父组件又是明确的了。

父组件获取子组件的服务

虽然一般情况下父组件依赖的子组件是明确的,但是父组件不能在父组件实例化时就立即获取子组件对应的服务,因为子组件可能并没有实例化。 比如子组件不满足 v-if 的条件。那么此时子组件就没有实例化,当然也就不能获取子组件对应的服务。

虽然不能在实例化阶段立即获取子组件以及子组件对应的服务,但是可以通过 findService 在运行时实时查询子组件对应的服务。 比如在用户点击某个按钮时,在事件处理回调函数中可以调用 findService 实时查询子组件的服务,此时是通过业务逻辑来保证子组件一定是存在的。 当然也可以不存在,只时需要做判空处理。

需要注意findService(token)需要 1 个参数,这个参数是子组件服务的 token。

子组件获取父组件的服务

虽然子组件在定义阶段不能确定父组件是谁,但是在实例化阶段是可以立即获取父组件对应的服务的。 因为子组件在实例化阶段,父组件是一定已经完成实例化的,所以此时父组件对应的服务已经存在了,子组件自然就可以获取父组件对应的服务了。

在子组件的实例化阶段,可以直接使用 useService 直接获取父组件的服务。

需要注意useService(token)需要 1 个参数,这个参数是父组件服务的 token,但是useService需要依赖getCurrentInstancehasInjectionContext,也就是useService只能在 setup 环境下使用。

总结

在组件定义阶段,父组件是知道自己依赖哪些子组件的。但是子组件却不知道自己的父组件是谁。

在组件实例化阶段,子组件是可以立即获取父组件以及父组件对应的服务的,但是父组件却不能立即获取子组件实例以及对应的服务,因为不能保证子组件 100%存在。