使用TypeScript
編寫Vue
項目也已經有了一段時間,筆者在剛剛使用TypeScript
時候也是很茫然,不知道從何下手,感覺使用TypeScript
寫項目感覺很累贅並不像JavaScript
那么靈活,因為TypeScript
對於代碼限制太多,在寫代碼的過程中時不時的就會拋出一個令你意想不到的錯誤,這一點筆者也是爬了不小的坑。可以使用了TypeScript
一段時間之后,才知道TypeScript
那是真的香(誰都逃不過的真香定理,O(∩_∩)O)。
筆者在之前使用Vue
的時候,曾經提到過如何在項目中使用依賴注入的概念,使用依賴注入主要有兩個目的:
- 解放Vuex
- 將頁面表現與業務邏輯相互拆分
同樣在使用TypeScript
編寫項目的過程中同樣也是使用了這種思路,但是也有些許的不一樣的地方,筆者對於項目結構是這樣划分的:
├─api // 請求數據接口
├─assets // 靜態資源
├─components // 組件
│ ├─base // 基礎組件
│ └─business // 業務組件
├─domain // 業務邏輯
├─interface // 接口
│ ├─other // 其他接口
│ ├─public // 公用接口
│ └─views // 頁面接口
├─middleware // 中間件
├─mixins // 混入層
├─router // 路由層
├─store // 全局狀態管理
├─style // 樣式
│ ├─components // 組件
│ │ ├─base // 基礎組件樣式
│ │ └─business // 業務組件樣式
│ ├─public // 公用樣式
│ └─views // 頁面樣式
└─views // 頁面
這樣看上去,每一層都有其自己的職責不會項目影響只是相互依賴,對於項目的維護來說是很友好的,這里會出現一個問題,為什么要對項目結構進行划分呢?筆者所理解的是:
- 降低各個功能之間的耦合
- 靈活調配各個模塊之間的依賴
- 每個模塊各盡其責
- 使項目有利於維護以及團隊協作
也已經說過各個分層之間有依賴關系,他們之間如何依賴又應該如何調配呢?對於前端來講無論是什么項目,都是依賴於頁面展開工作的,那么必定是以views
層為中心,views
又需要依賴於router
,router
需要注入到vue
實例當中。

上圖中assets
沒有提及到,對於assets
用來存儲一些靜態文件,這一層盡量不要去與基礎組件之間耦合在一起,這樣做的話若其他項目用到該組件的時候,該組件就變了味道。
其實這里筆者想着重說的一點是,domain
和views
之間的引用,對於我來說業務層是用來拆分業務,使views
和domain
之間各做自己的事情,views
更加的去關注頁面該如何去展示數據,然而domain
更加的關注業務邏輯部分。
domeDomain.ts
// 引入api
import domeAPI from "@/api/domainAPI.ts";
// 引入intaerface
import {tableItemInterface,queryDataInterface} from "@/interface/domeInterface.ts";
class DomeDomain {
public async getTableList (target: Object, propertyName: string, propertyDescriptor: PropertyDescriptor):PropertyDescriptor{
const data:queryDataInterface = propertyDescriptor.value();
propertyDescriptor.value = async function ():Promise<tableItemInterface[]>{
// 這里是業務邏輯
const {result:tableItemInterface[]} = await domeAPI.getTableList(data);
return result as Promise<tableItemInterface[]>;
}
return propertyDescriptor;
}
}
export default DomeDomain;
dome.vue
<template>
<div>
<el-table :data="list"/>
</div>
</template>
<script lang="ts">
import { Component, Vue} from 'vue-property-decorator';
// 引入intaerface
import {tableItemInterface,queryDataInterface} from "@/interface/domeInterface.ts";
// 引入業務類
import DomeDomain from "@/domain/DomeDomain.ts";
const domeDomain = new DomeDomain();
@Component()
export default class AddChargesButton extends Vue {
private tableList:tableItemInterface[] = [];
private queryData:queryDataInterface = {};
private pageInfo:{page:number,size:number}:{ page:1,
size:20};
@domeDomain.getTableList
private async getTableList(data:queryDataInterface):Promise<{pageInfo:any,query:queryDataInterface}>{
let {queryData:query,pageInfo} = this;
return {query,pageInfo};
}
private async queryTableList():Promise<void>{
try{
this.pageInfo.page = 2;
let {list} = await this.getTableList();
this.tableList = list;
}catch(error){
this.$message.error(error.message || error);
}
}
}
</script>
在上面的代碼中,domeDomain
中定義了一個getTableList
的方法,因為這個地方需要使用修飾符的形式去修飾方法,用於去請求數據,然而在頁面中的方法,可以無限次的復用,調用該方法的時候也可以對其參數進行調整之后再進行數據請求。
不用再去擔心參數的的傳遞,只需要把所有的參數整合好,調用其對應的獲取數據的方法就行了很方便。同樣也達到了業務和頁面表現的拆分。然而好處並不僅僅只有這些。相對應的在項目中同樣解脫了store
。讓store
做應該做的事情。
如果只是為了拆分業務的話不僅僅只限定於這一中方法,同樣也可以直接再頁面中使用domain
業務類的實例,去調用實例的方法,或者是使用混入把業務部分使用混入的形式混入到對應的頁面中。
對於裝飾器還有很多更高深的用法,我也在不斷的摸索中,個人覺得這些東西都是有利於項目的開發的。寫這篇文章只是想和更多同學一起交流學習,若文章中又什么不對的地方,可以在下方留言討論。