前言
筆者上一篇文章:
主要寫了
typescript
的用法和核心知識點總結, 這篇文章將透過一個實際的前端案例來教大家如何在專案中使用
typescript
。
你將收穫
如何使用
umi
快速搭建一個基於
React
+
antd
+
typescript
的前端專案
中後臺前端專案的目錄和
ts
檔案劃分
在React元件中使用
typescript
在工具庫中使用
typescript
網際網路黑白牆
案例分析
正文
在開始文章之前, 我們先看一下
企業黑白牆
專案的演示:
趣談前端
(注: 本文僅針對專案剖析和學習使用, 不做任何商業用途)
該專案是一個響應式網站, 針對PC端和H5均做了一定的適配, 接下來我們將正對該網站做一次
typescript
剖析。
由上面的gif可以看出網站的資訊結構圖大致如下:
趣談前端
接下來進入我們的正文。
1。 使用umi快速搭建一個基於React+antd+typescript的前端專案
umi
是一個功能強大且開箱即用的企業級專案腳手架, 這裡筆者直接採用umi來建立一個
ts
專案, 具體方式如下:
// 1。建立專案空目錄$ mkdir ts-react && cd ts-react// 2。建立專案yarn create @umijs/umi-app// 3。安裝專案依賴yarn
用umi開發只需要簡單的3個命令即可, 值得注意的是, 在執行步驟2時會在命令列出現如下互動選項:
主要是讓我們選擇建立的專案型別的, 這裡我們選typescript和antd即可, 有關如何建立可互動的命令列工具, 在筆者的 基於react/vue生態的前端整合解決方案探索與總結 中有介紹, 感興趣的可以學習交流。
經過以上的步驟我們就初步搭建了一個支援
react + typescript + antd
技術棧的專案骨架。
2。 中後臺前端專案的目錄和ts檔案劃分
我們先看看本次研究的專案的目錄劃分:
ts-react ├─ src │ ├─ assets │ │ └─ yay。jpg │ ├─ components │ │ └─ PublicModal │ │ ├─ index。css │ │ ├─ index。tsx │ │ └─ type。ts │ ├─ layouts │ │ ├─ __tests__ │ │ │ └─ index。test。tsx │ │ ├─ index。css │ │ └─ index。tsx │ ├─ locales │ │ └─ en-US。ts │ ├─ models │ ├─ pages │ │ ├─ __tests__ │ │ │ ├─ __mocks__ │ │ │ │ └─ umi-plugin-locale。ts │ │ │ └─ index。test。tsx │ │ ├─ about │ │ │ ├─ components │ │ │ ├─ index。d。ts │ │ │ ├─ index。less │ │ │ └─ index。tsx │ │ ├─ index。css │ │ ├─ index。tsx │ │ ├─ innerRec。tsx │ │ └─ list。tsx │ ├─ utils │ │ ├─ tool。ts │ │ └─ type。ts │ ├─ app。ts │ └─ global。css ├─ global。d。ts ├─ package。json ├─ readme。md ├─ tsconfig。json └─ typings。d。ts
我們從外往裡看, 在專案根目錄下有
typings.d.ts
和
global.d.ts
這兩個檔案, 前者我們可以放置一些全域性的匯出模組,比如css,less, 圖片的匯出宣告, 這樣我們就不用一個個的在頁面程式碼裡再重新聲明瞭, 如下:
// typings。d。tsdeclare module ‘*。css’;declare module ‘*。less’;declare module “*。png”;declare module “*。jpeg”;
這樣做我們就能避免在頁面中匯入
css
或者圖片檔案時
ts
報錯的問題了。 對於
global.d.ts
, 筆者建議放一些全域性宣告的變數, 介面等, 比如說Jquery這種第三方庫的宣告, window下全域性變數的宣告等。
其次是src目錄,我們具體介紹一下目錄的意義:
assets
存放靜態資源如圖片/影片/音訊等, 參與webpack的打包過程
layouts
存放公共佈局
components
存放全域性共同元件
locales
多語言配置目錄
models
dva的models資料夾, 處理redux流
pages
存放頁面的目錄, 內部可以有頁面元件components, 結構類似於全域性的components *
utils
存放js工具庫, 請求庫等公共js檔案
在瞭解了上面的目錄和目錄的含義之後, 我們再來看看如何規劃其中的ts檔案。
對於元件庫來說, 其下面的一個子目錄對應一個元件, 裡面包含必須的樣式檔案, 元件tsx檔案和元件自有型別檔案, 這裡命名為type。ts, 專門存放該元件所需要的型別和介面宣告。
同理對於頁面資料夾來說, 也應具有類似的結構, 就好比上面的about頁面, 包含如下結構:
components
該頁面專有的元件目錄
index.tsx
關於頁面的主檔案
index.less
關於頁面的樣式檔案
type.ts
關於頁面的型別和介面宣告檔案
還需要說明一點的是, 如果某個頁面有私有的型別或者介面宣告,我們可以直接在檔案內部去宣告, 沒必要全部都拿到外面去定義和宣告。
目錄規劃這塊基本完成, 實際情況還是需要根據自身專案結構來做更合理的劃分, 接下來我們看看具體的typescript在業務程式碼中的應用。
3。 在React元件中使用typescript
這裡筆者將會拿該專案的
自定義上傳元件
以及
白名單頁面
作為例子, 檔案上傳元件筆者將採用
SFC
(即函式元件), 白名單頁面將採用
類元件
, 這樣可以方便大家對這兩中元件開發模式下的typescript開發有個全面的認知。
3。1 自定義上傳元件開發
自定義上傳元件我們主要應用在釋出模組, 基於antd進行二次封裝以便能相容支援antd的Form模型, 如下圖:
趣談前端
結合typescript的實現如下:
import React, { useState, useEffect, SFC, ReactNode } from ‘react’;import { Upload, message } from ‘antd’;import { LoadingOutlined, PlusOutlined } from ‘@ant-design/icons’;import styles from ‘。/index。less’;export interface BeforeUploadFunc { (file:File, fileList:FileList): boolean | Promise
以上程式碼我們使用了React的函式元件, React提供了函式元件的型別
SFC
, 內建了children所以我們不用顯示的再宣告一次。 其他的比如函式宣告, 泛型介面, 可選型別的設定等筆者在上一篇文章:
徐小夕:TS核心知識點總結及專案實戰案例分析
有詳細介紹。不懂的可以在評論區與我交流。
3。2 白名單頁面開發
在瞭解完函式式元件如何與typescript搭配使用之後, 我們再來看看類元件。 我們那拿搜尋列表頁作為例子來講解:
程式碼如下:
import React from ‘react’;import { List, Avatar, Button, Skeleton, Tag, Modal } from ‘antd’;import styles from ‘。/index。less’;import req from ‘@/utils/req’;export interface IProps extends Location {}interface List { name: string; img: string; desc: string; isLoading?: boolean;}interface LoadingState { initLoading: boolean; loading: boolean;}export interface IState extends LoadingState { data: Array; list: Array
;}class LoadMoreList extends React。Component
以上程式碼實現了
class
元件的
typescript
應用, 對於
interface
型別宣告用到了繼承, 當然也可以不用繼承直接寫型別宣告, 這裡主要為了學習方便。 大家也可以把公用的頁面型別放到單獨的
type.ts
目錄下複用。
4。 在工具庫中使用typescript
在掌握了類元件和函式元件的typescript寫法之後, 我們來說說工具類的typescript編寫方式, 這塊比較簡單, 筆者簡單舉幾個常用工具函式, 將其改造成typescript的模式。 程式碼如下:
// utils/tool。ts/* * @Author: Mr Jiang。Xu * @Date: 2019-06-06 11:23:05 * @Last Modified by: Mr Jiang。Xu * @Last Modified time: 2019-06-29 22:33:52 *//** * 識別ie——淺識別 */export const isIe = ():boolean => { let explorer = window。navigator。userAgent; //判斷是否為IE瀏覽器 if (explorer。indexOf(“MSIE”) >= 0) { return true; }else { return false }}/** * 顏色轉換16進位制轉rgba * @param {String} hex * @param {Number} opacity */export function hex2Rgba(hex:string, opacity:number):string { if(!hex) hex = “#2c4dae”; return “rgba(” + parseInt(“0x” + hex。slice(1, 3)) + “,” + parseInt(“0x” + hex。slice(3, 5)) + “,” + parseInt(“0x” + hex。slice(5, 7)) + “,” + (opacity || “1”) + “)”;}// 去除html標籤export const htmlSafeStr = (str:string):string => { return str。replace(/<[^>]+>/g, “”)}interface params { [propertyName: string]: string | number}/* 解析url引數 */export const toParams = (params:params):string => { if(params){ let query = []; for(let key in params){ query。push(`${key}=${params[key]}`) } return `${query。join(‘&’)}` }else{ return ‘’ }}
以上是幾個比較簡單的案例, 方便大家入門和理解, 實際工作中場景會更復雜, 但是掌握了基本宣告和定義模式, 基本可以解決大部分ts宣告問題。 作為一名
前端工程師
,
typescript
的意義很大,雖然它增加了程式設計的複雜度和學習成本, 但是長遠來說, 對於團隊的編碼規範, 問題定位, 專案維護和程式碼管理的角度確實有不少積極作用, 所以學習
typescript
刻不容緩。
最後
如果想學習更多
H5遊戲
,
webpack
,
node
,
gulp
,
css3
,
javascript
,
nodeJS
,
canvas資料視覺化
等前端知識和實戰,歡迎在《趣談前端》專欄學習討論,共同探索前端的邊界。