react做h5 例子_从零搭建 React 开发 H5 模板
項目創建
創建項目文件夾
mkdir react-demo
cd react-demo
npm init -y
依賴安裝
yarn add react react-dom
yarn add webpack webpack-cli webpack-dev-server webpack-merge
babel-core babel-loader babel-polyfill babel-preset-env babel-preset-react
babel-preset-stage-0 cross-env
file-loader jsx-loader
css-loader style-loader url-loader less less-loader --dev
webpack 配置
區分開發環境?development?和生產環境?production 配置
分別創建對應的配置文件
antd-mobile 按需加載
安裝插件
yarn add babel-plugin-import -D
修改 babel.config.js 配置
module.exports = {
presets: ["@babel/preset-env", "@babel/preset-react"],
plugins: [
"@babel/plugin-transform-runtime",
"@babel/plugin-proposal-class-properties",
["import", { libraryName: "antd-mobile", style: true }]
]
};
externals 配置
webpack 中的 externals 防止將某些?import?的包(package)打包到 bundle 中
modules.export = {
plugins: [
new HtmlWebpackPlugin({
title: 'React Board',
files: { // 配置 CDN 引入
js: [
'//unpkg.com/swiper/js/swiper.min.js'
],
css: [
'//unpkg.com/swiper/css/swiper.min.css'
]
}
})
],
externals: {
swiper: 'Swiper'
}
}
index.html 設置:
代碼中使用:
import Swiper from 'swiper';
移動端適配
使用 postcss-loader實現 css 轉換
// 項目使用的是 less
yarn add postcss-less-loader -D
webpack.base.js 配置
{
test: /\.(css|less)$/,
use: [
'style-loader',
'css-loader',
'less-loader',
'postcss-less-loader'
]
}
有兩種轉換方案:
postcss-px-to-viewport
選用該插件對所有的 px 轉換成 vw 視窗尺寸
yarn add postcss-px-to-viewport -D
項目根目錄下建立?postcss.config.js
module.exports = {
plugins: {
"postcss-px-to-viewport": {
viewportWidth: 375, // 視窗的寬度,對應的是我們設計稿的寬度,Iphone6的一般是375 (xx/375*100vw)
viewportHeight: 667, // 視窗的高度,Iphone6的一般是667
unitPrecision: 3, // 指定`px`轉換為視窗單位值的小數位數(很多時候無法整除)
viewportUnit: "vw", // 指定需要轉換成的視窗單位,建議使用vw
selectorBlackList: ['.ignore', '.hairlines'],// 指定不轉換為視窗單位的類,可以自定義,可以無限添加,建議定義一至兩個通用的類名
minPixelValue: 1, // 小于或等于`1px`不轉換為視窗單位,你也可以設置為你想要的值
mediaQuery: false, // 允許在媒體查詢中轉換`px`
exclude: /(node_module)/i // 忽略 UI 組件庫
}
}
}
postcss-plugin-px2rem
這個插件是對所有 px 轉換成 rem 尺寸單位
yarn add postcss-plugin-px2rem -D
postcss.config.js?配置:
module.exports = {
plugins: {
"postcss-plugin-px2rem": {
rootValue: 16,// 配合 rem.js 使用 750 的設計稿
unitPrecision: 5,
mediaQuery: true,
exclude: /(node_module)/i,
selectorBlackList: ['html', 'mp-', 'calendar', 'iconfont'], // 在 rem.js 全局作用下,排除指定的文件的影響
propBlackList: ['border'] // 過濾屬性
}
}
}
需要新建 rem.js 或者直接下載?lib-flexible
const viewportWidth = 750
// 基準大小
const baseSize = 32
// 設置 rem 函數
function setRem() {
// 當前頁面寬度相對于 750 寬的縮放比例,可根據自己需要修改。
const scale = document.documentElement.clientWidth / viewportWidth
// 設置頁面根節點字體大小
document.documentElement.style.fontSize = (baseSize * Math.min(scale, 2)) + 'px'
}
// 初始化
setRem()
// 改變窗口大小時重新設置 rem
window.onresize = function () { setRem() }
在入口文件引入:
// App.js
import './utils/rem'
// import "./utils/flexible.js"
EsLint 配置
安裝 eslint 插件
yarn add eslint eslint-plugin-import babel-eslint eslint-plugin-react-hooks -D
根目錄下新建?.eslintrc.js?配置文件
module.exports = {
parser: "babel-eslint",
plugins: [
"react-hooks"
],
rules: {
"react-hooks/rules-of-hooks": "error", // 檢查 Hook 的規則
"react-hooks/exhaustive-deps": "error" // 檢查 effect 的依賴
}
}
React 路由
yarn add react-router-dom react-router-config
使用 react-router-config 來簡化路由配置
新建 routes.js 文件
import Home from "@/pages/Home"
import Me from "@/pages/Me"
import Test from "@/pages/Test"
console.log(typeof process.env.API)
const routes = [
{
path: "/home",
exact: true,
component: Home
},
{
path: "/me",
exact: true,
component: Me
},
{
path: "/test",
exact: true,
component: Test
}
];
export default routes;
根文件 App.js 中引入路由:
import { renderRoutes } from 'react-router-config'
import routes from './routes'
import { HashRouter as Router } from 'react-router-dom'
import Layouts from "./components/Layouts";
function App() {
return (
{renderRoutes(routes)}
)
}
ReactDOM.render(, document.getElementById('root'))
Hooks 開發
Hook 是什么?
Hook 是一個特殊的函數,它可以讓你“鉤入” React 的特性。Hook 只能再 Function Component 里面聲明。
useState
返回一個狀態和一個可以修改狀態的函數?setter
import React, { useState } from 'react';
import { Button } from "antd-mobile";
function User() {
const [user, setUser] = useState('Mondo')
return (
{user}setUser('imondo.cn')}>改變 State
)
}
useEffect
替代?Class Component中?componentDidMount、componentDidUpdate、componentWillUnmount?等部分生命周期
import React, { useState, useEffect } from 'react';
function User() {
const [user, setUser] = useState('Mondo')
useEffect(() => {
setTimeout(() => {
setUser("js.imondo.cn")
}, 2000)
}, [user]) // 僅在 user 更改時更新
return (
{user}setUser('imondo.cn')}>改變 State
)
}
useContext
接收一個 context 對象并返回該 context 的當前值。當前的 context 值由上層組件中距離當前組件最近的 的 value prop 決定。當組件上層最近的 更新時,該 Hook 會觸發重渲染。
可用于組件間值傳遞
import React, { useContext } from 'react';
const theme = {
color: "red"
}
const UserContext = React.createContext(theme);
function User() {
...
return (
)
}
function Child() {
const theme = useContext(UserContext);
return (
context)
}
useMemo
使用格式:useMemo(() => fn, deps)
把“創建”函數和依賴項數組作為參數傳入?useMemo,它僅會在某個依賴項改變時才重新計算 memoized 值。這種優化有助于避免在每次渲染時都進行高開銷的計算。可以當作 vue 中的計算屬性
import React, { useState, useMemo } from 'react';
import { Button } from "antd-mobile";
function User() {
const [user, setUser] = useState(1)
/* 緩存計算屬性 */
const data = useMemo(() => ({
users: (user + 1)
}), [user]);
const onChangeUser = (e) => {
setUser(+e.target.value);
}
return (
{data.users}setUser(user + 1)}>改變 State
)
}
useReducer
使用格式:const [state, dispatch] = useReducer(reducer, initialArg, init)
它是 useState 的替代方案,在一些場景使用:
state 邏輯較復雜且包含多個子值
下一個 state 依賴于之前的 state
最重要的其實它的寫法和 redux差不多
import React, { useReducer } from "react";
import { Button } from "antd-mobile";
let initCount = 0;
function reducer(state = initCount, action) {
switch (action) {
case "increment":
state++
return state
case "decrement":
state--
return state
default:
throw new Error();
}
}
function User() {
const [count, disaptch] = useReducer(reducer, initCount)
return (
useReducer計數器{count}disaptch("decrement")}>減
disaptch("increment")}>加
)
}
useRef
返回一個可變的 ref 對象,其?.current?屬性被初始化為傳入的參數
如果想要訪問子組件內的 ref 對象,子組件需要用 class 聲明組件。
import React, { useState, useMemo, useRef } from 'react';
function Parent() {
let [count, setCount] = useState(0)
const childRef = useRef(null)
const childClick = (val) => {
childRef.current.setState({
num: 2
});
}
return (
組件傳值
向子組件傳值
);
}
class Child1 extends React.Component {
constructor() {
super(...arguments);
this.state = {
num: 1
}
}
render() {
const { num } = this.state;
return (
ref 組件{num})
}
}
歡迎關注公眾號,大家一起共同交流和進步。
總結
以上是生活随笔為你收集整理的react做h5 例子_从零搭建 React 开发 H5 模板的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 琴岛学院计算机应用技术,我院计算机工程系
- 下一篇: 医学计算机应用研究的意义,医学图像感兴趣