TypeScript在Vuex4中使用TS實(shí)戰(zhàn)分享
簡介
雖然TypeScript
知識點(diǎn)學(xué)了很多,但是在實(shí)際項(xiàng)目中很多小伙伴還并不知道怎么用,今天筆者結(jié)合Vuex4
來使用TypeScript
實(shí)戰(zhàn)一下。
本文分vuex4
類型 Api
分析和vuex4
實(shí)戰(zhàn)兩部分講述。
首先我們來分析下 vuex4
的類型 Api
createStore
我們可以先看看createStore
方法,發(fā)現(xiàn)它需要傳遞一個泛型,并且這個泛型會應(yīng)用到state
上。
export function createStore<S>(options: StoreOptions<S>): Store<S>; export interface StoreOptions<S> { state?: S | (() => S); getters?: GetterTree<S, S>; actions?: ActionTree<S, S>; mutations?: MutationTree<S>; modules?: ModuleTree<S>; plugins?: Plugin<S>[]; strict?: boolean; devtools?: boolean; }
GetterTree
我們可以看到getters
的類型GetterTree
接收了兩個泛型。
export interface GetterTree<S, R> { [key: string]: Getter<S, R>; }
這兩個泛型分別應(yīng)用在本模塊state
上和根state
上。
export type Getter<S, R> = (state: S, getters: any, rootState: R, rootGetters: any) => any;
MutationTree
我們可以看到mutations
的類型MutationTree
只接收了一個泛型。
export interface MutationTree<S> { [key: string]: Mutation<S>; }
并且這個泛型只應(yīng)用到本模塊state
上。
export type Mutation<S> = (state: S, payload?: any) => any;
ActionTree
我們可以看到actions
的類型ActionTree
接收了兩個泛型。
export interface ActionTree<S, R> { [key: string]: Action<S, R>; }
并且也將這兩個泛型分別應(yīng)用在本模塊state
上和根state
上。我們還可以看到,由于action
支持對象和方法形式的寫法,所以Action
的類型是ActionHandler
和ActionObject
的聯(lián)合類型。
export type Action<S, R> = ActionHandler<S, R> | ActionObject<S, R>; export type ActionHandler<S, R> = (this: Store<R>, injectee: ActionContext<S, R>, payload?: any) => any; export interface ActionContext<S, R> { dispatch: Dispatch; commit: Commit; state: S; getters: any; rootState: R; rootGetters: any; }
ModuleTree
我們可以看到modules
的類型ModuleTree
只接收了一個泛型。并且將這個泛型傳遞到了Module
里面。
export interface ModuleTree<R> { [key: string]: Module<any, R>; }
我們可以發(fā)現(xiàn),module
的類型和createStore
的StoreOptions
是非常像的。
因?yàn)槟K本身也有自己的state、getters、actions、mutations、modules
export interface Module<S, R> { namespaced?: boolean; state?: S | (() => S); getters?: GetterTree<S, R>; actions?: ActionTree<S, R>; mutations?: MutationTree<S>; modules?: ModuleTree<R>; }
了解了vuex4
類型 Api
接下來我們就進(jìn)入到實(shí)戰(zhàn)環(huán)節(jié)了。
實(shí)戰(zhàn)
首先我們需要使用vuecli
創(chuàng)建一個TypeScript
的項(xiàng)目。
整體目錄結(jié)構(gòu)
筆者store整體目錄結(jié)構(gòu)如下:
index.ts
和以前的還是一樣,用來創(chuàng)建根store
并導(dǎo)出根store
。interfaces.ts
用來存放store
的類型。modules.ts
和以前的還是一樣,用來存放模塊。
首先定義根state的類型
// interfaces.ts type Info = { address: string }; export interface IRootState { name: string; age: number; info: Info; }
在創(chuàng)建store的時候?qū)⒏鵶tate的類型傳遞進(jìn)去。
// index.ts import { createStore, Store } from "vuex"; import { InjectionKey } from "vue"; import { IRootState } from "./interfaces"; export default createStore<IRootState>({ state: { name: "root", age: 0, info: { address: "" }, }, getters: { getRootName(state) { return state.name; }, getRootInfo(state) { return state.info; }, }, mutations: {}, actions: {}, });
并且需要導(dǎo)出key
// index.ts export const key: InjectionKey<Store<IRootState>> = Symbol();
在Vue實(shí)例使用store的時候?qū)ey一并傳入。
// main.ts import store, { key } from "@/store"; createApp(App).use(store, key).mount("#app");
在vue組件使用
這樣我們在vue
組件就能享受到TypeScript
的優(yōu)勢啦。
注意這里的useStore()
,也需要我們把key
傳遞進(jìn)去。
import { useStore } from "vuex"; import { key } from "@/store"; setup() { const store = useStore(key); return { rootName: store.state.name, }; },
可以看到,我們使用state
的時候就會被自動提示啦。
并且當(dāng)你使用不存在的屬性時會在我們編寫代碼的時候就會直接報錯提示。
相較js
,大大提高了開發(fā)效率不說,還減少了bug
。
自定義useStore()方法
如果覺得每次useStore()
,還需要我們把key
傳遞進(jìn)去麻煩的話,我們可以創(chuàng)建自己的useStore()
方法。
// index.ts import { useStore as baseUseStore } from "vuex"; export function useStore() { return baseUseStore(key); }
這樣我們在vue
組件使用store
的時候引入自己的useStore
方法就可以啦。
import { useStore } from "@/store"; setup() { const store = useStore(); return { rootName: store.state.name, }; },
我們知道,在實(shí)際項(xiàng)目中只創(chuàng)建一個根store
是遠(yuǎn)遠(yuǎn)不夠的。一般我們都會使用modules
。下面筆者介紹下怎么使用modules
。
modules的使用
模塊的類型是Module
,并且需要傳遞本模塊state
類型和根state
類型。
本模塊state
類型需要傳遞進(jìn)去我們可以理解,但是為什么要傳遞根state
類型呢?
因?yàn)槲覀兊?code>getters和actions
參數(shù)里面是有rootState
的,所以需要引入根state
類型。
// modeuls/test1.ts import { Module } from "vuex"; import { IRootState, ITest1State } from "../interfaces"; const Test1: Module<ITest1State, IRootState> = { state: { name: "test1", count: 0, }, getters: { getTest1Name(state) { return state.name; }, getAllName(state, rootState) { return state.name + rootState.age; }, }, }; export default Test1;
創(chuàng)建好模塊后我們需要在根store
里面引入進(jìn)去,引入方式和以前還是一樣。
并且我們需要把模塊的state
類型一并傳遞到InjectionKey
中和根state
類型形成交叉類型,并重新生成key
。
// index.ts import { createStore, Store, useStore as baseUseStore } from "vuex"; import { InjectionKey } from "vue"; import { IRootState, ITest1State } from "./interfaces"; import test1 from "./modeuls/test1"; export default createStore<IRootState>({ // ... modules: { test1: test1, // ...多個模塊,類似 }, }); // 定義模塊類型 type Modules = { test1: ITest1State; // ...多個模塊,類似 }; // 使用交叉類型形成新的key export const key: InjectionKey<Store<IRootState & Modules>> = Symbol();
我們來看看在vue
組件中的使用效果。
我們可以發(fā)現(xiàn),當(dāng)我們使用state
的時候,test1
模塊也會被提示出來
并且它里面的屬性也會被直接提示出來
好了,實(shí)戰(zhàn)環(huán)節(jié)就講述的差不多了,小伙伴們時候都懂了呢?
總結(jié)
雖然vuex4
對TypeScript
有了很好的支持,但是筆者覺得還是不夠的。
比如 使用麻煩,每次需要定義一個key
,還需要把可以傳遞到vue
的use
方法里面,并且在使用useStore
的時候也還需要將key
傳遞進(jìn)去,無疑增加了開發(fā)成本。
其次,這樣的配置并不會對getters、mutations、actions
生效,只會對state
有提示。
和pinia
比起來,整體使用體驗(yàn)還是會差很多。如果想學(xué)習(xí)pinia,并想了解pinia和vuex區(qū)別的話可以看看TypeScript Pinia實(shí)戰(zhàn)分享(Vuex和Pinia對比梳理總結(jié))一文。
到此這篇關(guān)于TypeScript在Vuex4中使用TS實(shí)戰(zhàn)分享的文章就介紹到這了,更多相關(guān)TypeScript Vuex4內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
利用onresize使得div可以隨著屏幕大小而自適應(yīng)的代碼
javascript 利用onresize使得div可以隨著屏幕大小而自適應(yīng)的代碼2010-01-01JavaScript中的作用域與閉包、原型與原型鏈、異步與單線程
JavaScript的三座大山指的是:作用域和閉包、原型和原型鏈、異步與單線程,這些概念在日常的開發(fā)工作中經(jīng)常被提及,并對我們理解和編寫高質(zhì)量的JavaScript代碼至關(guān)重要2024-02-02一文詳解Javascript內(nèi)存機(jī)制與垃圾回收
這篇文章主要給大家詳細(xì)介紹了Javascript的內(nèi)存機(jī)制與垃圾回收,文中又詳細(xì)的代碼示例,對我們學(xué)習(xí)Javascript有一定的幫助,需要的同學(xué)可以借鑒閱讀2023-06-06JS實(shí)現(xiàn)網(wǎng)頁滾動條感應(yīng)鼠標(biāo)變色的方法
這篇文章主要介紹了JS實(shí)現(xiàn)網(wǎng)頁滾動條感應(yīng)鼠標(biāo)變色的方法,實(shí)例分析了javascript針對鼠標(biāo)事件的操作技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-02-02JavaScript實(shí)現(xiàn)淘寶網(wǎng)圖片的局部放大功能
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)淘寶網(wǎng)圖片的局部放大功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-05-05JS查找字符串中出現(xiàn)最多的字符及個數(shù)統(tǒng)計
最近在項(xiàng)目中遇到這樣的需求:求字符串'nininihaoa'中出現(xiàn)次數(shù)最多字符。怎么實(shí)現(xiàn)呢?下面小編給大家分享具體實(shí)現(xiàn)代碼,需要的朋友參考下吧2017-02-02layui關(guān)閉彈窗后刷新主頁面和當(dāng)前更改項(xiàng)的例子
今天小編就為大家分享一篇layui關(guān)閉彈窗后刷新主頁面和當(dāng)前更改項(xiàng)的例子,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09