TypeScript編寫Vue項目結構解析

使用TypeScript編寫Vue項目也已經有了一段時間,筆者在剛剛使用TypeScript時候也是很茫然,不知道從何下手,感受使用TypeScript寫項目感受很累贅並不像JavaScript那麼靈活,由於TypeScript對於代碼限制太多,在寫代碼的過程當中時不時的就會拋出一個令你意想不到的錯誤,這一點筆者也是爬了不小的坑。可使用了TypeScript一段時間以後,才知道TypeScript那是真的香(誰都逃不過的真香定理,O(∩_∩)O)。javascript

筆者在以前使用Vue的時候,曾經提到過如何在項目中使用依賴注入的概念,使用依賴注入主要有兩個目的:html

  1. 解放Vuex
  2. 將頁面表現與業務邏輯相互拆分

一樣在使用TypeScript編寫項目的過程當中一樣也是使用了這種思路,可是也有些許的不同的地方,筆者對於項目結構是這樣劃分的:前端

├─api           //  請求數據接口
├─assets        //  靜態資源
├─components    //  組件
│  ├─base           //  基礎組件
│  └─business       //  業務組件
├─domain        //  業務邏輯
├─interface     //  接口
│  ├─other          //  其餘接口
│  ├─public         //  公用接口
│  └─views          //  頁面接口
├─middleware    //  中間件
├─mixins        //  混入層
├─router        //  路由層
├─store         //  全局狀態管理
├─style         //  樣式
│  ├─components     //  組件  
│  │  ├─base            // 基礎組件樣式 
│  │  └─business        // 業務組件樣式
│  ├─public         //  公用樣式
│  └─views          //  頁面樣式
└─views         //  頁面

這樣看上去,每一層都有其本身的職責不會項目影響只是相互依賴,對於項目的維護來講是很友好的,這裏會出現一個問題,爲何要對項目結構進行劃分呢?筆者所理解的是:vue

  1. 下降各個功能之間的耦合
  2. 靈活調配各個模塊之間的依賴
  3. 每一個模塊各盡其責
  4. 使項目有利於維護以及團隊協做

也已經說過各個分層之間有依賴關係,他們之間如何依賴又應該如何調配呢?對於前端來說不管是什麼項目,都是依賴於頁面展開工做的,那麼一定是以views層爲中心,views又須要依賴於routerrouter須要注入到vue實例當中。java

項目結構依賴結構圖

上圖中assets沒有說起到,對於assets用來存儲一些靜態文件,這一層儘可能不要去與基礎組件之間耦合在一塊兒,這樣作的話若其餘項目用到該組件的時候,該組件就變了味道。api

其實這裏筆者想着重說的一點是,domainviews之間的引用,對於我來講業務層是用來拆分業務,使viewsdomain之間各作本身的事情,views更加的去關注頁面該如何去展現數據,然而domain更加的關注業務邏輯部分。dom

domeDomain.tsasync

//  引入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的方法,由於這個地方須要使用修飾符的形式去修飾方法,用於去請求數據,然而在頁面中的方法,能夠無限次的複用,調用該方法的時候也能夠對其參數進行調整以後再進行數據請求。this

不用再去擔憂參數的的傳遞,只須要把全部的參數整合好,調用其對應的獲取數據的方法就好了很方便。一樣也達到了業務和頁面表現的拆分。然而好處並不只僅只有這些。相對應的在項目中一樣解脫了store。讓store作應該作的事情。

若是隻是爲了拆分業務的話不只僅只限定於這一中方法,一樣也能夠直接再頁面中使用domain業務類的實例,去調用實例的方法,或者是使用混入把業務部分使用混入的形式混入到對應的頁面中。

對於裝飾器還有不少更高深的用法,我也在不斷的摸索中,我的以爲這些東西都是有利於項目的開發的。寫這篇文章只是想和更多同窗一塊兒交流學習,若文章中又什麼不對的地方,能夠在下方留言討論。

相關文章
相關標籤/搜索