React專案搭建
一.專案準備(此專案由React+TS實現)
1.建立專案,此處我們使用腳手架建立專案
npx create-react-app demo --template typescript
或者
yarn create react-app demo --template typescript
然後我們把專案進行一定的精簡,刪除不必要的檔案,修改index.tsx為下圖的樣子
2.進行專案解包
因為我們使用less進行樣式預處理,所以我們必須在webpack.config.js裡面進行配置,但是我們發現在專案裡面並 沒有看到這樣的一個檔案。原因是我們使用腳手架建立的專案,已經幫我們進行了一些重要的設定,如非必要,腳 手架不希望我們修改配置了。
所以我們需要進行專案的解包。解包的命令可以在 package.json > scripts
中找到
但是此時如果我們直接解包,會無法成功。因為解包是一個不可逆的過程,我們最好進行一次版本管理。所以我們 先 使用git先把之前的修改進行儲存。
git add .
git commit -m '解包前的備份'
然後我們就可以進行解包了
npm run eject
或者
yarn eject
解包完成後我們會在根目錄看到一個config資料夾,這個config資料夾就是我們要進行配置的地方
3.下載專案所需的依賴
專案中我們需要使用到的依賴比較多,所以我們先一次性下載好所有的依賴。
less和less-loader
npm i less less-loader --save--dev
或者
yarn add less less-loader --save--dev
react-router-dom
npm i react-router-dom@6 --save
或者
yarn add react-router-dom@6 --save
redux和react-redux
npm i redux react-redux --save
或者
yarn add redux react-redux --save
axios
npm i axios --save 或者 yarn add axios--save
mui , mui的官網
npm install @mui/material @emotion/react @emotion/styled
或者
yarn add @mui/material @emotion/react @emotion/styled
postcss-px-to-viewport
npm i postcss-px-to-viewport --save-dev
或者
yarn add postcss-px-to-viewport --save-dev
4.配置移動端螢幕適配
在前端發展過程中,最認可的螢幕適配方案主要有兩個,比較老的是media+rem,比較新的是viewport,這個專案採用viewport. 也就是說我們使用vw+vh來進行螢幕的適配,但是其實我們這個專案中只需要使用vw就夠了.
我們在config/webpack.config.js裡面進行配置,找到postcss-loader節點,在這個節點的plugins節點的裡面新增下面的配置.
require('postcss-px-to-viewport')({ viewportWidth: 1125, // 視口寬度,根據設計圖的大小 viewportHeight: 1000, // 視口高度,根據設計圖的大小 unitPrecision: 6,// 保留小數點 viewportUnit: 'vw', // 單位 selectorBlackList: [], // 排除的類 minPixelValue: 1, // px的最小單位 mediaQuery: false, // 排除媒體查詢 landscapeUnit: 'vw', // 橫屏單位 fontViewportUnit: 'vw' // 字型屬性單位 })
值得注意的是 plugins
節點有一個三元判斷,需要在兩個分支上都新增這段程式碼。
5.配置less-loader
我們下載好了less-loader後,需要在config/webpack.config.js裡面進行配置,找到module/rules節點,在最後一個sass-loader後新增less-loader的配置
{ test: /\.less$/, use: getStyleLoaders({}, 'less-loader') }
6.配置@指向
首先還是找到config/webpack.config.js裡面,找到resolve/alias節點,在最後新增下面程式碼:
"@": path.join(__dirname, "../src")
然後還是找到tsconfig.json,在compilerOptions節點的最後節點的最後新增
"baseUrl": "./", "paths": { "@/*": ["src/*"] }
注意:以上修改 webpack.config.js 的所有步驟,都需要重啟腳手架方能生效。
7.解決移動端的點選延遲
我們通常會使用fastclick解決移動端的點選延遲問題,在index.htm裡面新增如下程式碼.
<title>IT猿題庫</title> <script src="https://as.alipayobjects.com/g/component/fastclick/1.0.6/fastclick.js"></script> <script> if ('addEventListener' in document) { document.addEventListener('DOMContentLoaded', function() { FastClick.attach(document.body); }, false); } if(!window.Promise) { document.writeln('<script src="https://as.alipayobjects.com/g/component/es6-promise/3.2.2/es6-promise.min.js"'+'>'+'<'+'/'+'script>'); } </script>
三.配置路由
我們在src目錄下新建一個router資料夾,然後在裡面新建一個index.tsx.路由配置如下:
import {BrowserRouter,Routes,Route} from "react-router-dom" import Login from "../views/Login" import App from "../App" import Home from "../views/Home" import Fast from "../views/Fast" import Mine from "../views/Mine" import SelectPractice from "../views/Select" import Practice from "../views/Practice" const router = ( <BrowserRouter> <Routes> <Route path="/login" element={<Login />}></Route> <Route path="/" element={<App />}> <Route index element={<Home />}></Route> <Route path="home" element={<Home />}></Route> <Route path="fast" element={<Fast />}></Route> <Route path="mine" element={<Mine />}></Route> <Route path="select" element={<SelectPractice />}></Route> <Route path="practice" element={<Practice />}></Route> </Route> </Routes> </BrowserRouter> ); export default router;
然後自己在views目錄下新建路由對應的元件,在入口的index.tsx
中渲染我們的路由。同時記得要在App元件中新增<Outlet/>
import router from "./router"; const rootEl = document.getElementById("root"); const root = ReactDOM.createRoot(rootEl!); root.render(router);
至此專案目錄快照如下:
5.配置Store
專案中肯定會有部分資料需要共享的,所以我們需要使用react-redux進行全域性資料共享。
先在src
目錄上新建store
目錄,在裡面新建 index.ts
檔案,寫入下面程式碼。
/* 使用TS的方式建立store 1.createStore 2.需要定義state和action的型別 */ import {createStore} from "redux" const defState:IRootState={ count:100 } const reducer=(state:IRootState=defState,action:IStateAction)=>{
state = JSON.parse(JSON.stringify(state));
return state
}
const store=createStore(reducer) export default store;
其中 IStoreState
和 IStoreAction
是兩個interface
,我們需要在 src/types
目錄下新建一個 store.d.ts
進行宣告。
.d.ts
檔案用於宣告一些全域性可用的型別資料。
// xxx.d.ts是ts裡面用於全域性地宣告型別的檔案 interface IRootState{ count:number } interface IStateAction{ type:string; payload:any }
最後在入口的index.tsx
裡面使用 Provider
元件進行資料共享。
import router from "./router"; import { Provider } from "react-redux"; import store from "./store"; const rootEl = document.getElementById("root"); const root = ReactDOM.createRoot(rootEl!); root.render(<Provider store={store}>{router}</Provider>);
示例:在Fast元件中使用store裡面資料
import { useSelector } from "react-redux"; // 快速刷題頁面 export default function Fast() { const count = useSelector((state: IRootState) => state.count); return <div>Fast{count}</div>; }