资料
静态地址: git@gitee.com:huruqing/villa-static-less.git
知识点目录
(一) 路由配置
创建组件: 首页,目的地,提交需求,发现,我的
- 在app.js配置路由
- Router 最外层需要用Router进行包裹(只需一次)
- Switch 表示只匹配一个路由地址,跟js的switch类似
- Route 用来配置路由,包括路由地址和路由组件
- exact 精确匹配
- Redirect 重定向 ```javascript import React from “react”; import { BrowserRouter as Router, Switch, Link, Route, Redirect, } from “react-router-dom”; import Index from “./views/home/index”; import Target from “./views/target/index”; import Need from “./views/need/index”; import Discover from “./views/discover/index”; import My from “./views/my/index”;
export default function () { return (
<a name="RRpEI"></a>
## (二) hooks
函数组件中没有state, 也没有生命周期, hooks可以在函数组件中使用state
<a name="DGb1p"></a>
##### (1) useState
1. 在函数组件中使用useState来定义响应式数据, 接收一个参数(变量的默认值)
1. `setKeyword`相当于之前的`setState`, 用来修改keyword的值
```javascript
import React, { useState } from 'react';
export default function() {
// 定义响应式数据keyword,keyword的默认值是 ''
let [keyword,setKeyword] = useState('');
return(
<div>
<button onClick={()=>{setKeyword('哈哈哈哈哈')}}>修改关键字</button>
<p>
{keyword}
</p>
</div>
)
}
(2) useEffect
- 中括号内的变量发生了改变, 就会触发回调函数
请求后台接口可以放在useEffect的函数里执行, 中括号为空或者不要中括号
let [keyword,setKeyword] = useState('');
useEffect(()=> {
console.log(2222);
// 当keyword发生变化时,会触发回调函数
},[keyword])
(三) 静态页面
修改注释
- class变className
- React项目使用短路径, 跟 ../../../../地狱模式说拜把
项目的根目录下创建jsconfig.json
文件,并添加以下代码。
{
"compilerOptions": {
"baseUrl": "src"
},
"include": ["src"]
}
// 使用
import axios from "../../../utils/request"; // 以前的写法
import axios from "utils/request";
- 图片的引用问题
最佳实践: 写静态的时候, 如果图片来自网上, 随便用网上的一张图片暂代, 等 拿到数据再使用变量代替
方式1: 支持完整路径
<img sr="https://mall.s.maizuo.com/aaa.png"/>
方式2: 使用import
import bg from 'assest/img/bg.png'
<img src={bg} alt=""/>
- 渲染还可以这样写
```html
{
list.map(item=>(
- 11111
- 22222
// 类似vue的template的做法 { list.map(item=>( <>
6. react渲染html字符串(类似vue的v-html指令)
```javascript
let htmlStr = ` <ul class="nav fcc bg-fff">
<li class="fg1 ifcc item active">推荐•路线</li>
<li class="fg1 ifcc item">推荐•路线</li>
<li class="fg1 ifcc item">推荐•路线</li>
</ul>`
export default function() {
return (
<div className="pt-15 bg-fff" dangerouslySetInnerHTML={{ __html:htmlStr}}></div>
)
}
(四) classnames
类似vue绑定class的操作
// 判断条件为true时会给div添加class类 on
<div className={classnames("flex jc-sa",{on:判断条件}}></div>
// 实际应用
import React from 'react';
import classnames from 'classnames';
export default function() {
let curr = '01';
return(
<div className="demo-index">
<li className={classnames("flex f18 jc-sb",{on: curr==='01'})}>111</li>
<li className={classnames("flex f18 jc-sb",{on: curr==='02'})}>222</li>
<li className={classnames("flex f18 jc-sb",{on: curr==='03'})}>333</li>
</div>
)
}
(五) 底部栏tab切换高亮
- 使用footer的组件就是footer的父组件
- 父组件给footer传一个参数currTab
- footer根据currTab的值判断要不要高亮tab
```html
import React from “react”;
import “./Footer.scss”;
import { Link } from “react-router-dom”;
import classNames from “classnames”;
import shouye from ‘assest/img/shouye.png’;
import shouyeing from ‘assest/img/shouyeing.png’;
import mudi from ‘assest/img/mudi.png’;
import mudiing from ‘assest/img/mudiing.png’;
import xingqiu from “assest/img/xingqiu.png” import xingqiuing from “assest/img/xingqiuing.png” import wode from “assest/img/wode.png” import wodeing from “assest/img/wodeing.png”
// 使用此组件的, 需要传入属性curr export default function (props) { let curr = props.curr;
return (
<Link
to="/target"
className={classNames("box flex aic fdc", { on: curr === "02" })}
>
<img src={curr === "02"?mudiing:mudi} alt="" />
<div className="text mt-5 f999">目的地</div>
</Link>
<Link
to="/need"
className={classNames("box flex aic fdc", { on: curr === "03" })}
>
<img src="assest/img/tijiao.png" alt="" />
<div className="text mt-5 f999">提交需求</div>
</Link>
<Link
to="/discover"
className={classNames("box flex aic fdc", { on: curr === "04" })}
>
<img className="mt-5" src={curr==='04'?xingqiuing:xingqiu} alt="" />
<div className="text mt-5 f999">发现</div>
</Link>
<Link
to="/my"
className={classNames("box flex aic fdc", { on: curr === "05" })}
>
<img src={curr==='05'?wodeing:wode} alt="" />
<div className="text mt-5 f999">我的</div>
</Link>
<Link
to="/demo"
className={classNames("box flex aic fdc", { on: curr === "06" })}
>
<img src="assest/img/wode.png" alt="" />
<div className="text mt-5 f999">demo</div>
</Link>
</div>
</div>
); }
<a name="FswRF"></a>
## (六) 导入ant-design
[https://mobile.ant.design/docs/react/introduce-cn#3.-%E4%BD%BF%E7%94%A8](https://mobile.ant.design/docs/react/introduce-cn#3.-%E4%BD%BF%E7%94%A8)
1. 安装依赖 `npm install antd-mobile --save`
1. 复制以下代码,放入 public/index.html的头部
```html
<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>
- 在根目录的index.js, 添加antd的样式文件
import 'antd-mobile/dist/antd-mobile.css';
- 使用 ```html import React from “react”; import { Button } from ‘antd-mobile’;
export default function() { return }
<a name="ce1Gr"></a>
## (七) 路由跳转和传参
路由跳转:
```javascript
1. 使用 <Link to="xxx" />
2. 使用history
- 如果是class组件, 使用this.props.history.push();
- 函数组件则使用hooks
import {useHistory} from 'react-router';
let history = useHistory();
history.push();
(1) 动态路由传参
<Route path="/demo/:id" component={Demo} />
<Link to="/demo/22222" />
{props.match.params.id}
```html // 从其他页面跳转到 /demo import { useHistory } from “react-router-dom”; export default function () { const history = useHistory(); const goto = () => { history.push(“/demo/2222”); }; return (
// 路由配置 app.js
// demo.jsx import React from ‘react’;
export default function(props) { console.log(props); return(
<a name="bvz00"></a>
##### (2) query传参(页面刷新后参数不存在)
```jsx
// 核心代码
history.push({
pathname: '/my',
query:{
username: 'zs',
age: 100
}
})
// 接收
props.location.query;
// app.js的路由配置
<Route path="/demo" component={Demo} />
// 其他页面
import { useHistory } from "react-router-dom";
export default function () {
const history = useHistory();
const goto = () => {
history.push({
pathname: '/demo',
query: {
username: '法外狂徒'
},
state: {
age: 1000
}
});
};
return (
<div>
<button onClick={goto}>query&state</button>
</div>
);
}
// 接收参数
// query传参刷新页面就没有了,要主要使用&&以防报错
import React from "react";
export default function (props) {
let { query, state } = props.location;
return (
<div className="demo-index">
<p> query参数: {query && query.username}</p>
<p> state参数: {state.age}</p>
</div>
);
}
(3) state传参(页面刷新后参数还存在)
// 核心代码
history.push({
pathname: '/my',
state:{
username: 'zs',
age: 100
}
})
// 接收
props.location.state;
(4) search传参
(八) redux
(九) 性能优化PureComponent和useMemo
类(class)组件性能9优化可以使用shouldCompoentUpdate进行优化
// nextProps下一个属性(新的属性),nextState下一个状态(新的状态)
shouldComponentUpdate(nextProps, nextState) {
// 根据新的属性或者状态决定要不要更新页面
if(xxx) {
return true;
} else {
return false
}
}
类(class)组件, 可以让其继承React.PureComponent来实现优化
import React from "react";
class Demo extends React.PureComponent {
constructor(props){
super(props);
}
render() {
console.log(this.props);
return (<div>性能优化</div>)
}
}
export default Demo;
函数组件可以使用React.memo进行包装以实现优化
import React from "react";
function Scene(props) {
return <div>{props.name}</div>;
}
export default React.memo(Scene);