forked from vuejs/vuex
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Amirzhan Aliyev
committed
Dec 16, 2022
1 parent
3c70566
commit b9bd10a
Showing
1 changed file
with
134 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
# TypeScript Support | ||
|
||
Vuex предоставляет свою типизацию, поэтому вы можете использовать TypeScript для написания определения хранилища. Вам не нужна специальная конфигурация TypeScript для Vuex. Пожалуйста, следуйте [Базовой настройке TypeScript в Vue](https://v3.ru.vuejs.org/ru/guide/typescript-support.html), чтобы настроить свой проект. | ||
|
||
Однако, если вы пишете свои компоненты Vue на TypeScript, вам нужно выполнить несколько шагов, которые потребуют от вас правильного обеспечения типов для хранилища. | ||
|
||
## Типизация `$store` свойства в Vue компоненте | ||
|
||
Vuex не предоставляет типизацию для свойства `this.$store` из коробки. При использовании с TypeScript, вы должны объявить собственный модуль расширения. | ||
|
||
|
||
Для этого объявите пользовательскую типизацию для Vue `ComponentCustomProperties`, добавив файл деклараций в каталог вашего проекта: | ||
|
||
```ts | ||
// vuex.d.ts | ||
import { Store } from 'vuex' | ||
|
||
declare module '@vue/runtime-core' { | ||
// объявите собственные состояния хранилища | ||
interface State { | ||
count: number | ||
} | ||
|
||
// укажите типизацию для `this.$store` | ||
interface ComponentCustomProperties { | ||
$store: Store<State> | ||
} | ||
} | ||
``` | ||
|
||
## Типизация функции композиции `useStore` | ||
|
||
Когда вы пишете свой компонент Vue в Composition API, вы, скорее всего, захотите, чтобы `useStore` возвращал типизированное хранилище. Чтобы `useStore` правильно возвращал типизированное хранилище, вы должны: | ||
|
||
1. Определить типизированный `InjectionKey`. | ||
2. Указать типизированный `InjectionKey` при установке хранилища в приложение Vue. | ||
3. Передать типизированный `InjectionKey` методу `useStore`. | ||
|
||
Давайте разбираться с этим шаг за шагом. Во-первых, определите ключ используя Vue интерфейс `InjectionKey` вместе с вашим собственным определением типизации хранилища: | ||
|
||
```ts | ||
// store.ts | ||
import { InjectionKey } from 'vue' | ||
import { createStore, Store } from 'vuex' | ||
|
||
// определите свою типизацию для состояния хранилища | ||
export interface State { | ||
count: number | ||
} | ||
|
||
// определите ключ внедрения | ||
export const key: InjectionKey<Store<State>> = Symbol() | ||
|
||
export const store = createStore<State>({ | ||
state: { | ||
count: 0 | ||
} | ||
}) | ||
``` | ||
|
||
Затем передайте определенный ключ внедрения при установке хранилища в Vue приложение: | ||
|
||
```ts | ||
// main.ts | ||
import { createApp } from 'vue' | ||
import { store, key } from './store' | ||
|
||
const app = createApp({ ... }) | ||
|
||
// передайте ключ внедрения | ||
app.use(store, key) | ||
|
||
app.mount('#app') | ||
``` | ||
|
||
В заключение, вы можете передать ключ методу `useStore` для получения типизированного хранилища. | ||
|
||
```ts | ||
// в vue компоненте | ||
import { useStore } from 'vuex' | ||
import { key } from './store' | ||
|
||
export default { | ||
setup () { | ||
const store = useStore(key) | ||
|
||
store.state.count // типизировано как число | ||
} | ||
} | ||
``` | ||
|
||
Под капотом Vuex устанавливает хранилище в приложение Vue, используя функции Vue [Provide/Inject](https://v3.ru.vuejs.org/ru/api/composition-api.html#provide-inject) поэтому ключ внедрения важный фактор. | ||
|
||
### Упрощение использования `useStore` | ||
|
||
Необходимость импортировать `InjectionKey` и передавать его в `useStore` везде, где он используется, может быстро превратиться в повторяющуюся задачу. Чтобы упростить задачу, вы можете определить свою собственную компонуемую функцию для получения типизированного хранилища: | ||
|
||
```ts | ||
// store.ts | ||
import { InjectionKey } from 'vue' | ||
import { createStore, useStore as baseUseStore, Store } from 'vuex' | ||
|
||
export interface State { | ||
count: number | ||
} | ||
|
||
export const key: InjectionKey<Store<State>> = Symbol() | ||
|
||
export const store = createStore<State>({ | ||
state: { | ||
count: 0 | ||
} | ||
}) | ||
|
||
// определите собственную функцию композиции `useStore` | ||
export function useStore () { | ||
return baseUseStore(key) | ||
} | ||
``` | ||
|
||
Теперь, импортировав собственную компонуемую функцию, вы можете получить типизированное хранилище **без** необходимости предоставления ключа внедрения и его типизации: | ||
|
||
```ts | ||
// в vue компоненте | ||
import { useStore } from './store' | ||
|
||
export default { | ||
setup () { | ||
const store = useStore() | ||
|
||
store.state.count // типизировано как число | ||
} | ||
} | ||
``` |