1. Background
Expect to use the global event bus in the project vUE + TS. Add the event bus to the vUE prototype as follows:
Vue.prototype.$bus = new Vue();
Copy the code
To access the event bus from within the component,
This. $bus. $emit (' start - up, params) or enclosing $bus. $on (' start - up, () = > {... })Copy the code
Here this is an instance of Vue, since the prototype of vue has the $bus attribute. Therefore, all prototype-based VUE instances should also have access to the event bus. In theory, but in practice. The error message is as follows:
TS2339: Property '$bus' does not exist on type 'Vue'.
Copy the code
2. Error causes are reported
The compiler detects that the $bus attribute does not exist on the Vue object. For the compiler, the presence of the $bus attribute depends on whether the $bus attribute is explicitly defined on the Vue’s type declaration. Further, the compiler will report an error if attributes not defined in the vue.d. ts file are referenced on a Vue instance. Here is a look at the contents of the vue.d. ts file.
export interface Vue {
// attributes
readonly $el: Element;
readonly $options: ComponentOptions<Vue>;
readonly $parent: Vue;
readonly $root: Vue;
readonly $children: Vue[];
readonly $refs: { [key: string]: Vue | Element | Vue[] | Element[] };
readonly $slots: { [key: string]: VNode[] | undefined };
readonly $scopedSlots: { [key: string]: NormalizedScopedSlot | undefined };
readonly $isServer: boolean;
readonly $data: Record<string, any>;
readonly $props: Record<string, any>;
readonly $ssrContext: any;
readonly $vnode: VNode;
readonly $attrs: Record<string, string>;
readonly $listeners: Record<string, Function | Function[]>;
// operations
...
}
Copy the code
As you can see, there is no $bus attribute in Vue. Therefore, you need to add them manually. But we can’t go directly to node_modules/vue/types/vue. Which s file to add. Although it cannot be modified, we can expand the vue.d.ts file.
2. Practice
- Create a new Typings directory under the project’s SRC directory.
- Create a new vue-extend.ts file in the Typings directory.
- Fill in the following contents in the vue-extend.ts file.
import Vue from 'vue';
declare module 'vue/types/vue' {
interface Vue {
readonly $bus: any
}
}
Copy the code
3. Precautions
Don’t forget to introduce vUE in vue-extend.ts files. import Vue from ‘vue’;
4. Principle analysis
declare module 'vue/types/vue' {
interface Vue {
readonly $bus: any
}
}
Copy the code
The meaning of this code is in node_modules/vue/types/vue/index which s a module, declared in a file defined in the module internal interface called vue. But there is also an interface named vue in vue/types/vue.d.ts. Interfaces with the same name are automatically merged. See the official document merge interface for details.
5. Sample code
Complete the case