Компонент Vue JS typcript не может найти свойства экземпляра внедрения - PullRequest
1 голос
/ 15 марта 2019

Я работаю с машинопись и VUE.

В моем приложении есть service, который является глобальным для каждого подкомпонента.

Я нашел это собственное решение vue в vue JS, чтобы внедрить это свойство вдочерние компоненты.

на main.ts

const service = new MyService(...);

new Vue({
  router,
  provide() { return { service }; } // provide the service to be injected
  render: h => h(App),
}).$mount("#app");

на любом компоненте vue для машинописи

import Vue from "vue";

export default Vue.extend({
  inject: ["service"], // inject the service
  mounted() {
    console.log(this.service); // this.service does exists 
  },
});

Таким образом, я могу получить введенный serviceна моих дочерних компонентах.

Однако я получаю следующую ошибку

Свойство 'service' не существует для типа 'CombinedVueInstance >> '.

Как можно решить эту ошибку компиляции машинописи?

Ответы [ 2 ]

1 голос
/ 15 марта 2019

Использование плагинов

Если вы хотите использовать какой-либо сервис во всех компонентах Vue, вы можете попробовать использовать plugins .
В main.ts вы просто импортируете его:

import Vue from "vue";
import "@/plugins/myService";

В plugins/myService.ts вы должны написать что-то вроде этого:

import _Vue from "vue";
import MyService from "@/services/MyService";

export default function MyServicePlugin(Vue: typeof _Vue, options?: any): void {
    Vue.prototype.$myService = new MyService(...); // you can import 'service' from other place
}

_Vue.use(MyServicePlugin);

И в любом компоненте vue вы можете использовать это:

<template>
  <div> {{ $myService.name }}</div>
</template>
<script lang="ts">
  import { Component, Vue } from "vue-property-decorator";

  @Component
  export default class MyComponent extends Vue {
    private created() {
      const some = this.$myService.getStuff();
    }
  }
</script>

Не забудьте объявить $myService в файле d.ts. Где-то в вашем проекте добавьте файл myService.d.ts со следующим содержанием:

import MyService from "@/services/MyService";

declare module "vue/types/vue" {
  interface Vue {
      $myService: MyService;
  }
}
1 голос
/ 15 марта 2019

Использование декоратора свойств Vue

Vue-property-decorator , который внутренне реэкспортирует декораторы из vue-class-component , предоставляет серию декораторов машинописного текста, которые дают действительно хороший смысл. Вы должны использовать класс API хотя.

@Inject и @Provide - два таких декоратора:

В провайдере:

import {Vue, Component, Provide} from 'vue-property-decorator';

@Component
export default class MyClass {
  @Provide('service') service: Service = new MyServiceImpl(); // or whatever this is
}

В предоставленном компоненте:

import {Vue, Component, Inject} from 'vue-property-decorator';

@Component
export default class MyClass {
  @inject('service') service!: Service; // or whatever type this service has
  mounted() {
    console.log(this.service); // no typescript error here
  },
}

Я считаю, что это оптимальное решение, в том смысле, что оно дает лучший смысл при работе с Vue.

Однако теперь вы можете не захотеть изменять определение всех ваших компонентов или просто не можете этого сделать из-за внешних ограничений. В таком случае вы можете сделать следующий трюк:

Кастинг

Вы можете разыграть this любого, когда вы собираетесь использовать this.service. Не самая лучшая вещь, но она работает:

  mounted() {
    console.log((this as any).service);
  },

Должны быть другие способы, но я больше не привык к Vue.extends API. Если у вас есть время и возможность, я настоятельно рекомендую вам переключиться на API класса и начать использовать декораторы vue-property-decorators, они действительно дают лучший смысл.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...