Provide a way to change the type of `$root`
What problem does this feature solve?
We use root component as a global store.
createApp({
data: () => ({ loginInfo: { id: 1, name: 'a' } }),
});
So we can access loginInfo
easily in child components
<div>User name: {{$root.loginInfo.name}}</div>
It used to work very well, until we migrated to vue-tsc
+ volar
recently
error: 类型“ComponentPublicInstance<{}, {}, {}, {}, {}, {}, {}, {}, false, ComponentOptionsBase<any, any, any, any, any, any, any, any, any, {}>>”上不存在属性“userInfo”
What does the proposed API look like?
$root should be correctly typed as what user specified in createApp
. In my case ComponentPublicInstance<{}, {}, { loginInfo:{ id: number; name: string; } }
$root
and $parent
are generally typed as ComponentPublicInstance | null
, which makes them almost unusable in vue template. Even any
can be a better option than ComponentPublicInstance | null
like what we did for $el
$parent
cannot be typed because it depends on the runtime as a component could be the child of different components at runtime
$root
being a type, I don't think you can extend it in your codebase to add properties 🤔
You could however add a custom global property (https://v3.vuejs.org/api/application-config.html#globalproperties) which can be typed by extending the global types. In both scenarios, you will have to manually type your root app as there is no way to directly infer the global type of $root
in vue from a createApp()
call.
Note you can also do $root as Root
in templates by defining a global type Root in one of your global d.ts
files type Root = ComponentPublicInstance<{}, {}, { loginInfo:{ id: number; name: string; } }
In both scenarios, you will have to manually type your root app as there is no way to directly infer the global type of $root in vue from a createApp() call.
I was aware of it. In addition, there can be multiple createApp
s in one project.
$el
should have been typed as Node
, but we type $el
as any
because we know Node
is not useful.
So can we just type $root
as any
? Using $root
as a common ComponentPublicInstance
seems meaningless in Vue 3.
While in Vue 2, you may use $root as an event bus.