Vue3結合TS項目開發實踐:Composition API的風格理念、關注點分離、如何組織TS進行項目開發(采用聲明文件來管理接口及所需類型/目錄結構推薦)


一、composition Api

  compositon Api的本質體現在代碼里面,也就是一個setup函數,在這個setup函數中,返回的數據,會用到該組件的模板中。return的這個對象,一定程度上,代表了之前vue2中的data屬性。

  這時候,對於大多數初學者來說,可能存在的疑惑就是,那么我能不能定義options Api的寫法,比如data、computed、watch、methods等等。這里我需要明確的是,Vue3是完全兼容Vue2的這種options Api的寫法,但是從理念上來說,更加推薦setup的方式,來寫我們的組件。

  原因如下:Vue3的存在,本身是為了解決Vue2的問題的,Vue2的問題就是在於,聚合性不足,會導致代碼越來越臃腫!setup的方式,能夠讓data、方法邏輯、依賴關系等聚合在一塊,更方便維護。

  也就是說,以后我們盡量不要寫單獨的data、computed、watch、methods等等,不是Vue3不支持,而是和Vue3的理念違背

  components屬性,也就是一個組件的子組件,這個配置在Vue2和3的差異不大,Vue2怎么用,Vue3依然那么用。

  缺點:從options api切換到composition api最大的問題就是沒有強制的代碼分區,如果書寫的人沒有很好的代碼習慣,那么后續的人將會看的十分難受。所以在寫代碼時需要注意做到很好的“關注點分離”:

1、自我代碼分區並且盡量抽離方法(寫好注釋),分區如下:

(1)相關引入

(2)響應式數據、props、emit 定義

(3)生命周期以及 watch 書寫

(4)方法定義

(5)方法、屬性暴露

2、組件抽離:將頁面拆成兩個文件夾,一個為 views,一個為 components

  views 和 components 文件夾下有各自的文件。views 文件夾中為頁面入口,掌管數據,而 components 則為頁面中一些組件抽離。如果是公共組件,再抽離到 components 文件夾下其他位置。

3、hook 抽離:盡可能將邏輯抽離,並不一定要進行復用。

二、關注點分離

  關注點分離,應該分兩層意思:第一層意思就是,Vue3的setup,本身就把相關的數據,處理邏輯放到一起,這就是一種關注點的聚合,更方便我們看業務代碼。

  第二層意思,就是當setup變的更大的時候,我們可以在setup內部,提取相關的一塊業務,做到第二層的關注點分離

import { useStore } from "vuex"; import { useRouter } from "vue-router"; import { defineComponent, ref, computed } from 'vue'; import useMerchantList from './merchant.js'; export default defineComponent({ name: 'Gift', setup() { const counter = ref(0); const router = useRouter(); // router 的使用 const onClick = () => { router.push({ name: "AddGift" }); } // 在該示例中,我們把獲取商家列表的相關業務分離出去。也就是下面的merchant.ts
        const {merchantList} = useMerchantList(); return { counter, onClick, merchantList } } }) // merchant.ts import { getMerchantlist } from "@/api/rights/gift"; import { ref, onMounted } from "vue"; export default function useMerchantList(): Record<string, any> { const merchantList = ref([]); const fetchMerchantList = async () => { let res = await getMerchantlist({}); merchantList.value = res?.data?.child; }; onMounted(fetchMerchantList); // 周期函數的使用 return { merchantList }; }

三、TypeScript支持

  TS與Vue3項目開發息息相關,所以真的想用Vue3,我們還是得了解TS的使用。下面我們主要了解在業務場景中如何組織TS。

  使用TS進行業務開發,一個核心的思維是,先關注數據結構,再根據數據結構進行頁面開發。以前的前端開發模式是,先寫頁面,后關注數據。

  比如要寫一個禮品列表的頁面,我們可能要定義這么一些interface。總而言之,我們需要關注的是:頁面數據的interface、接口返回的數據類型、接口的入參類型等等。

// 禮品創建、編輯、列表中的每一項,都會是這個數據類型。
interface IGiftItem { id: string | number; name: string; desc: string; [key: string]: any; } // 全局相應的類型定義 // 而且一般來說,我們不確認,接口返回的類型到底是什么(可能是null、可能是對象、也可能是數組)
所以使用范型來定義interface
interface IRes<T> { code: number; msg: string; data: T } // 接口返回數據類型定義 interface IGiftInfo { list: Array<IGiftItem>; pageNum: number; pageSize: number; total: number; }

  在一個常見的接口請求中,我們一般使用TS這么定義一個數據請求,數據請求的req類型,數據請求的res類型

export const getGiftlist = ( params: Record<string, any> ): Promise<IRes<IGiftInfo>> => { return Http.get("/apis/gift/list", params); };

  目錄結構:在你編寫大型前端項目時,推薦使用聲明文件(Declaration Files)來管理接口或其他自定義類型。聲明文件一般是 <module_name>.d.ts 的形式,在這類文件中只定義模塊中的類型,沒有任何實際的實現邏輯。聲明文件可以單獨放在一個目錄里,我喜歡命名為 interfaces,意思就是接口。這樣,就可以充分將抽象類型、方法、屬性等與實際內容分開。以下例子是一個集成了 TS 的 Vue 項目目錄。

. ├── babel.config.js // Babel 編譯配置文件
├── jest.config.ts   // 單元測試配置文件
├── package.json    // 項目配置文件
├── public       // 公共資源
├── src         // 源代碼目錄
│   ├── App.vue     // 主應用
│   ├── assets     // 靜態資源
│   ├── components   // 組件
│   ├── constants    // 常量
│   ├── i18n      // 國際化
│   ├── interfaces   // 聲明文件目錄
│   │   ├── components  // 組件聲明
│   │   ├── index.d.ts  // 主聲明
│   │   ├── layout   // 布局聲明
│   │   ├── store    // 狀態管理聲明
│   │   └── views    // 頁面聲明
│   ├── layouts     // 布局
│   ├── main.ts     // 主入口
│   ├── router     // 路由
│   ├── shims-vue.d.ts // 兼容 Vue 聲明文件
│   ├── store      // 狀態管理
│   ├── styles     // CSS/SCSS 樣式
│   ├── test      // 測試
│   ├── utils      // 公共方法
│   └── views      // 頁面
└── tsconfig.json    // TS 配置文件

  其中可以看到,interfaces 這個目錄跟其他模塊在同一級,而其子目錄則是其他模塊所對應的類型聲明。編寫代碼前,盡量先創建並設計聲明文件內容,設計好之后再到實際的模塊下完成實現。當然,這個 “定義 -> 實現“ 是一個不斷迭代的過程,可能實現過程中發現有類型設計問題,可以回到聲明文件中完善定義,再到實現代碼里進行優化。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM