10

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?

2 Answers 2

17

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Just now noticed that I didn't fully read your question. For nested services, you'll need some sort of dependency injection container. You can then provide your container at top-level and use it to resolve your services.
1

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
}

1 Comment

how would we set the value of a reactivate parameter from inside the ParentComponent class? I can't seem to get this to work at all, only static values

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.