Как разрешить вводимые экземпляры в Vue.js с использованием TypeScript
Согласно официальному документу , кажется, что мы можем использовать функцию внедрения зависимостей, пока мы остаемся на объектно-ориентированной структуре.
Вот мой вопрос. Я использую TypeScript для достижения этой цели (на основе класса). Я собираюсь использовать Inversify
как контейнер МОК. Моя первоначальная идея была примерно такой:
DependencyConfig.ts
:
import { Container } from "inversify";
import "reflect-metadata";
import Warrior from "./interfaces/Warrior";
import { Ninja } from "./models/Warrior";
let container = new Container();
container.bind<Warrior>(Symbol("Warrior")).to(Ninja);
export default container;
App.ts
:
import container from "./DependencyConfig";
@Component({
name: "App",
provide: container
})
export default class App extends Vue {
}
Когда я зарегистрировался в консоли разработчика моего браузера, я смог увидеть container
было установлено в поле _provided
. Вот Hello.ts
, дочерний компонент App.ts
:
Hello.ts
:
@Component({
name: "Hello",
inject: [ "container" ]
})
export default class Hello extends Vue {
created (): void {
console.log(this);
}
}
Поскольку App.ts
может обращаться к Hello.ts
через vue-router
, он не регистрируется Hello.ts
как дочерний компонент. Я ожидал, что введенный контейнер должен появиться на _injected
или что-то подобное. Однако я не смог его найти. Я изменил значение свойства inject
с "container"
на { "container": Symbol("Container") }
, но так и не смог его найти.
Service Locator :
Это работает хорошо использовать сервис-локатор вместо пары provide/inject
:
// App.ts
@Component({
name: "App"
})
export default class App extends Vue {
}
// Hello.ts
import container from "./DependencyConfig";
@Component({
name: "Hello"
})
export default class Hello extends Vue {
created (): void {
var ninja = container.get<Ninja>(Symbol("Warrior"));
console.log(ninja.name);
}
}
Тем не менее, я хочу избежать использования шаблона Service locator здесь. Я что-то пропустил при использовании пары provide/inject
для инъекции зависимостей?
1 ответ:
Я нашел решение. Если мы используем
vue-class-component
и ещеvue-property-decorator
, мы можем достичь этой цели-используяprovide
/inject
пара. Вот мой фрагмент кода:// App.vue <script lang="ts"> import Vue from "vue"; import Component from "vue-class-component"; import SERVICE_IDENTIFIER from "./models/Identifiers"; import container from "./configs/DependencyConfigs"; @Component({ name: "App", // Provides IoC container at the top level of VueComponent provide: { [SERVICE_IDENTIFIER.CONTAINER]: container } }) export default class App extends Vue { } </script>
В самом верхнем компоненте Vue,
App.vue
, мы предоставляем экземплярcontainer
так, чтобы его все дочерние компоненты могли использовать его. Вот один из его дочерних компонентов,Ninja.vue
:// Ninja.vue <script lang="ts"> import Vue from "vue"; // Imports both Component and Inject decorators from vue-property-decorator, // instead of vue-class-component import { Component, Inject } from "vue-property-decorator"; import { Container } from "inversify"; import SERVICE_IDENTIFIER from "../models/Identifiers"; import { Ninja as _Ninja } from "../models/Warrior"; @Component({ name: "Ninja" }) export default class Ninja extends Vue { public warrior: string; public weapon: string; // IoC container provided from App.ts is injected here @Inject(SERVICE_IDENTIFIER.CONTAINER) private _container: Container; private _ninja: _Ninja; created (): void { this._ninja = this._container.get<_Ninja>(SERVICE_IDENTIFIER.WARRIOR); this.warrior = this._ninja.name; this.weapon = this._ninja.weapon.name; } } </script>
Дочерний компонент использует декоратор
@Inject(Symbol)
для разрешения введенного экземпляраcontainer
изApp.vue
.Я написал об этом сообщение в блоге в ианглийский икорейский об этом.
HTH