I'm using Vue.js with TypeScript and the vue-property-decorator package. In theory I can do something like this, according to the documentation:
import { Component, Inject, Provide, Vue } from 'vue-property-decorator'
const s = Symbol('baz')
@Component
export class MyComponent extends Vue {
@Provide() foo = 'foo'
@Provide('bar') baz = 'bar'
@Inject() foo: string
@Inject('bar') bar: string
@Inject(s) baz: string
}
However, what if I want to use @Provide
and @Inject
on a class that is not a component? For example, if I have ComponentA
that depends on ServiceA
that depends on ServiceB
. How can i set this up?
The provide() function accepts two arguments. The first argument is called the injection key, which can be a string or a Symbol . The injection key is used by descendent components to lookup the desired value to inject.
TypeScript also improves developer ergonomics via type-based auto-completion in IDEs. Vue is written in TypeScript itself and provides first-class TypeScript support. All official Vue packages come with bundled type declarations that should work out-of-the-box.
Now that Vue. js officially supports TypeScript, it's possible to create TypeScript projects from scratch using Vue CLI. However, you still need some third-party packages with custom decorators and features to create a true, complete TypeScript application.
You provide anything you want from a higher component by using the @Provide
decorator, and then ask for it in a lower component by using @Inject
. For example:
In the parent component, you provide the value using @Provide(<someKey>)
//Parent.vue
<template>
<div>The parents value: {{this.providedValue}}</div>
<child />
</template>
<script lang="ts">
import { Component, Vue, Provide} from 'vue-property-decorator';
import Child from './Child.vue';
@Component({components: Child})
export default class Parent extends Vue {
@Provide('key') private providedValue: string = 'The value';
}
</script>
Now we've declared a value with the name key
that can be consumed by all children, multiple levels deep:
//Child.vue
<template>
<div>The childs value: {{this.injectedValue}}</div>
</template>
<script lang="ts">
import { Component, Vue, Inject } from 'vue-property-decorator';
@Component
export default class Child extends Vue {
@Inject('key') private injectedValue!: string;
}
</script>
The property injectedValue
will now be injected by Vue by walking up on the hierarchy until it finds a provided value with the key key
.
If you want something dependency injection-like, it's best to provide the value at the top, where you create your Vue instance:
//index.ts
import Vue from 'vue';
//... imports and configs
new Vue({
el: '#app',
// Provide values by returning a key-value pair
provide: () => ({
'key1': 'value1',
'key2': 'value2'
}),
render: h => h(App)
});
Now you can use @Inject('key1')
in any component of this Vue instance.
You may use vue 3 and class style component, then you have to define provider/inject by this way:
in vue 3 except Component annotation there is Options annotation and we use it to define provide/inject parameters. More info
// Parent component
import { Vue, Options } from "vue-class-component";
import { computed } from "@vue/reactivity";
@Options({
provide: {
staticParameter: 'static value',
reactiveParameter: computed(() => 'Normal computed value'),
},
})
export default class ParentComponent extends Vue {}
// Child component
import { Vue, Options } from "vue-class-component";
@Options({
inject: ["staticParameter", "reactiveParameter"],
})
export default class Timer extends Vue {
staticParameter!: string;
reactiveParameter!:string
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With