Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use provide/inject with TypeScript but without vue-class-component

When I use provide/inject with class components everything works as expected. But when I use it in a "normal" vue component I get type-errors.

In this example I get errors when referencing this.testService. The code works though.

export default Vue.extend({
  name: "HelloWorldBasic" as string,
  inject: ["testService"],

  computed: {
    message(): string | null {
      return this.testService ? this.testService.hello() : null;
    }
  }
});

Where did I make my mistake? How should I write the code?

I set up a small project to be able to reproduce it and work with it:

$ git clone [email protected]:schnetzi/vue-provide-inject.git
$ npm ci
$ npm start
like image 320
schnetzi Avatar asked Oct 29 '19 18:10

schnetzi


People also ask

How do you use provide and inject in Vue?

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. A single component can call provide() multiple times with different injection keys to provide different values.

How do you make provide and inject reactive?

Vue 2 offered the Provide/Inject API and now it's been enhanced and improved in Vue 3. To make the data reactive, start by using the provide option as a function. Then, wrap your data inside a computed() function to make it reactive and read-only.

Does Vue have dependency injection?

To handle dependency injection in Vue, the provide and inject options are provided out of the box.

How do I use typescript in Vue components?

When using TypeScript in single-file Vue components, the Vue library must be imported so you can extend from it. Since you will not be using the class-style syntax, you use the as keyword to declare data as a data type. For things like const, let, var, or a function return type, you can define its type with the colon (:).

What is provide/inject in VUE 3?

Luckily for us, Vue has the provide / inject API, and with the introduction of the Composition API in Vue 3, it has never been better. Using the provide and inject pair, parent components can send data to their children components regardless of how deep the component hierarchy is.

How to use a custom data type in a Vue component?

You can now use this custom data type in any Single-File Vue Component ( .vue) or TypeScript ( .ts) file. Here is an example for App.vue that uses the User interface and displays the firstName and lastName: In order to use TypeScript in this component, you will need to add a lang attribute to the script tag of your component.

Does typescript vue plugin support Vue SFC imports in TS files?

At the same time, plain TS files are still handled by VSCode's built-in TS language service, which is why we need TypeScript Vue Plugin to support Vue SFC imports in TS files. This default setup works, but for each project we are running two TS language service instances: one from Volar, one from VSCode's built-in service.


1 Answers

This is a bit tricky to do, but it is possible using the same workaround that is commonly used for mixins, which entails defining an interface for whatever you want to add to the Vue instance.

In your case, here's how it would be done:

import Vue_ from 'vue';
import MyTestServiceType from 'wherever/it/is';

interface HelloWorldBasicInjected {
  testService: MyTestServiceType
}

const Vue = Vue_ as VueConstructor<Vue_ & HelloWorldBasicInjected>
export default Vue.extend({
  name: "HelloWorldBasic" as string,
  inject: ["testService"],

  computed: {
    message(): string | null {
      return this.testService ? this.testService.hello() : null;
    }
  }
});
like image 173
Varo Avatar answered Nov 15 '22 13:11

Varo