资料

  1. 静态地址: git@gitee.com:huruqing/villa-static-less.git

    知识点目录

    (一) 路由配置

  2. 创建组件: 首页,目的地,提交需求,发现,我的

  3. 在app.js配置路由
    1. Router 最外层需要用Router进行包裹(只需一次)
    2. Switch 表示只匹配一个路由地址,跟js的switch类似
    3. Route 用来配置路由,包括路由地址和路由组件
    4. exact 精确匹配
    5. 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 (

{/ 配置路由:路由地址和路由组件 /}
); }

  1. <a name="RRpEI"></a>
  2. ## (二) hooks
  3. 函数组件中没有state, 也没有生命周期, hooks可以在函数组件中使用state
  4. <a name="DGb1p"></a>
  5. ##### (1) useState
  6. 1. 在函数组件中使用useState来定义响应式数据, 接收一个参数(变量的默认值)
  7. 1. `setKeyword`相当于之前的`setState`, 用来修改keyword的值
  8. ```javascript
  9. import React, { useState } from 'react';
  10. export default function() {
  11. // 定义响应式数据keyword,keyword的默认值是 ''
  12. let [keyword,setKeyword] = useState('');
  13. return(
  14. <div>
  15. <button onClick={()=>{setKeyword('哈哈哈哈哈')}}>修改关键字</button>
  16. <p>
  17. {keyword}
  18. </p>
  19. </div>
  20. )
  21. }

(2) useEffect
  1. 中括号内的变量发生了改变, 就会触发回调函数
  2. 请求后台接口可以放在useEffect的函数里执行, 中括号为空或者不要中括号

    1. let [keyword,setKeyword] = useState('');
    2. useEffect(()=> {
    3. console.log(2222);
    4. // 当keyword发生变化时,会触发回调函数
    5. },[keyword])

    (三) 静态页面

  3. 修改注释

  4. class变className
  5. React项目使用短路径, 跟 ../../../../地狱模式说拜把

项目的根目录下创建jsconfig.json文件,并添加以下代码。

  1. {
  2. "compilerOptions": {
  3. "baseUrl": "src"
  4. },
  5. "include": ["src"]
  6. }
  7. // 使用
  8. import axios from "../../../utils/request"; // 以前的写法
  9. import axios from "utils/request";
  1. 图片的引用问题

最佳实践: 写静态的时候, 如果图片来自网上, 随便用网上的一张图片暂代, 等 拿到数据再使用变量代替

  1. 方式1: 支持完整路径
  2. <img sr="https://mall.s.maizuo.com/aaa.png"/>
  3. 方式2: 使用import
  4. import bg from 'assest/img/bg.png'
  5. <img src={bg} alt=""/>
  1. 渲染还可以这样写 ```html { list.map(item=>(
    • 11111
    • 22222
    )) }

// 类似vue的template的做法 { list.map(item=>( <>

11111
22222
</> )) }

  1. 6. react渲染html字符串(类似vuev-html指令)
  2. ```javascript
  3. let htmlStr = ` <ul class="nav fcc bg-fff">
  4. <li class="fg1 ifcc item active">推荐•路线</li>
  5. <li class="fg1 ifcc item">推荐•路线</li>
  6. <li class="fg1 ifcc item">推荐•路线</li>
  7. </ul>`
  8. export default function() {
  9. return (
  10. <div className="pt-15 bg-fff" dangerouslySetInnerHTML={{ __html:htmlStr}}></div>
  11. )
  12. }

(四) classnames

类似vue绑定class的操作

  1. // 判断条件为true时会给div添加class类 on
  2. <div className={classnames("flex jc-sa",{on:判断条件}}></div>
  3. // 实际应用
  4. import React from 'react';
  5. import classnames from 'classnames';
  6. export default function() {
  7. let curr = '01';
  8. return(
  9. <div className="demo-index">
  10. <li className={classnames("flex f18 jc-sb",{on: curr==='01'})}>111</li>
  11. <li className={classnames("flex f18 jc-sb",{on: curr==='02'})}>222</li>
  12. <li className={classnames("flex f18 jc-sb",{on: curr==='03'})}>333</li>
  13. </div>
  14. )
  15. }

(五) 底部栏tab切换高亮

  1. 使用footer的组件就是footer的父组件
  2. 父组件给footer传一个参数currTab
  3. 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 (

项目实践 - 图1
首页

  1. <Link
  2. to="/target"
  3. className={classNames("box flex aic fdc", { on: curr === "02" })}
  4. >
  5. <img src={curr === "02"?mudiing:mudi} alt="" />
  6. <div className="text mt-5 f999">目的地</div>
  7. </Link>
  8. <Link
  9. to="/need"
  10. className={classNames("box flex aic fdc", { on: curr === "03" })}
  11. >
  12. <img src="assest/img/tijiao.png" alt="" />
  13. <div className="text mt-5 f999">提交需求</div>
  14. </Link>
  15. <Link
  16. to="/discover"
  17. className={classNames("box flex aic fdc", { on: curr === "04" })}
  18. >
  19. <img className="mt-5" src={curr==='04'?xingqiuing:xingqiu} alt="" />
  20. <div className="text mt-5 f999">发现</div>
  21. </Link>
  22. <Link
  23. to="/my"
  24. className={classNames("box flex aic fdc", { on: curr === "05" })}
  25. >
  26. <img src={curr==='05'?wodeing:wode} alt="" />
  27. <div className="text mt-5 f999">我的</div>
  28. </Link>
  29. <Link
  30. to="/demo"
  31. className={classNames("box flex aic fdc", { on: curr === "06" })}
  32. >
  33. <img src="assest/img/wode.png" alt="" />
  34. <div className="text mt-5 f999">demo</div>
  35. </Link>
  36. </div>
  37. </div>

); }

  1. <a name="FswRF"></a>
  2. ## (六) 导入ant-design
  3. [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)
  4. 1. 安装依赖 `npm install antd-mobile --save`
  5. 1. 复制以下代码,放入 public/index.html的头部
  6. ```html
  7. <script src="https://as.alipayobjects.com/g/component/fastclick/1.0.6/fastclick.js"></script>
  8. <script>
  9. if ('addEventListener' in document) {
  10. document.addEventListener('DOMContentLoaded', function() {
  11. FastClick.attach(document.body);
  12. }, false);
  13. }
  14. if(!window.Promise) {
  15. document.writeln('<script src="https://as.alipayobjects.com/g/component/es6-promise/3.2.2/es6-promise.min.js"'+'>'+'<'+'/'+'script>');
  16. }
  17. </script>
  1. 在根目录的index.js, 添加antd的样式文件
    1. import 'antd-mobile/dist/antd-mobile.css';
  2. 使用 ```html import React from “react”; import { Button } from ‘antd-mobile’;

export default function() { return }

  1. <a name="ce1Gr"></a>
  2. ## (七) 路由跳转和传参
  3. 路由跳转:
  4. ```javascript
  5. 1. 使用 <Link to="xxx" />
  6. 2. 使用history
  7. - 如果是class组件, 使用this.props.history.push();
  8. - 函数组件则使用hooks
  9. import {useHistory} from 'react-router';
  10. let history = useHistory();
  11. history.push();

(1) 动态路由传参
  1. <Route path="/demo/:id" component={Demo} />
  2. <Link to="/demo/22222" />
  3. {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(

动态路由参数: {props.match.params.id}
) }

  1. <a name="bvz00"></a>
  2. ##### (2) query传参(页面刷新后参数不存在)
  3. ```jsx
  4. // 核心代码
  5. history.push({
  6. pathname: '/my',
  7. query:{
  8. username: 'zs',
  9. age: 100
  10. }
  11. })
  12. // 接收
  13. props.location.query;
  1. // app.js的路由配置
  2. <Route path="/demo" component={Demo} />
  3. // 其他页面
  4. import { useHistory } from "react-router-dom";
  5. export default function () {
  6. const history = useHistory();
  7. const goto = () => {
  8. history.push({
  9. pathname: '/demo',
  10. query: {
  11. username: '法外狂徒'
  12. },
  13. state: {
  14. age: 1000
  15. }
  16. });
  17. };
  18. return (
  19. <div>
  20. <button onClick={goto}>query&state</button>
  21. </div>
  22. );
  23. }
  24. // 接收参数
  25. // query传参刷新页面就没有了,要主要使用&&以防报错
  26. import React from "react";
  27. export default function (props) {
  28. let { query, state } = props.location;
  29. return (
  30. <div className="demo-index">
  31. <p> query参数: {query && query.username}</p>
  32. <p> state参数: {state.age}</p>
  33. </div>
  34. );
  35. }

(3) state传参(页面刷新后参数还存在)
  1. // 核心代码
  2. history.push({
  3. pathname: '/my',
  4. state:{
  5. username: 'zs',
  6. age: 100
  7. }
  8. })
  9. // 接收
  10. props.location.state;

(4) search传参

(八) redux

详见使用redux共享状态一文

(九) 性能优化PureComponent和useMemo

  1. 类(class)组件性能9优化可以使用shouldCompoentUpdate进行优化

    1. // nextProps下一个属性(新的属性),nextState下一个状态(新的状态)
    2. shouldComponentUpdate(nextProps, nextState) {
    3. // 根据新的属性或者状态决定要不要更新页面
    4. if(xxx) {
    5. return true;
    6. } else {
    7. return false
    8. }
    9. }
  2. 类(class)组件, 可以让其继承React.PureComponent来实现优化

    1. import React from "react";
    2. class Demo extends React.PureComponent {
    3. constructor(props){
    4. super(props);
    5. }
    6. render() {
    7. console.log(this.props);
    8. return (<div>性能优化</div>)
    9. }
    10. }
    11. export default Demo;
  3. 函数组件可以使用React.memo进行包装以实现优化

    1. import React from "react";
    2. function Scene(props) {
    3. return <div>{props.name}</div>;
    4. }
    5. export default React.memo(Scene);

    https://www.jianshu.com/p/b3d07860b778