react-router路由

安装

npm i react-router-dom --save
复制代码

容器组件

  • BrowserRouter 浏览器自带的H5 API, restful 风格,须要配合后台;
  • HashRouter 使用 hash 方式进行路由,路径后均有#
  • MemoryRouter 在内存中管理 history ,地址栏不会变化。在 reactNative 中使用。

路由的使用

  1. 跑通路由
//Home.js

import React,{Component}from 'react'
export default class Home extends Component{
    render(){
        return(
        <div>
        Home
        </div>
        )
    }
}

//User.js

import React,{Component}from 'react'
export default class Home extends Component{
    render(){
        return(
        <div>
      User
        </div>
        )
    }
}

//Profile.js

import React,{Component}from 'react'
export default class Home extends Component{
    render(){
        return(
        <div>
        Home
        </div>
        )
    }
}

//index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { HashRouter, Router, Route } from 'react-router-dom'

import Home from './components/Home'
import User from './components/User'
import Profile from './components/Profile'


ReactDOM.render(<HashRouter>
  <div>
    <Route path="/home" component={Home} />
    <Route path="/profile" component={Profile} />
    <Route path="/user" component={User} />
  </div>
</HashRouter>, document.getElementById('root'));
复制代码
  • HashRouter 只能包含一个根元素 所以在全部的Route的外层包了一个div标签 尽可能放在高的位置 好比主入口的index文件 是一个组件 直接加上<> 就可使用 由于只有在HashRouter下面配置的Route路由才有用
  • Route 组件有两个属性
    • path
    • component 当浏览器地址栏中的url和path匹配时会显示component属性对应的组件

路由匹配规则

  • 如有一个组件 但愿任何路由都显示时 把path的值设置为/

Link组件 是 react-router-dom的内置组件 起做用和VueRouter 和 router-link 相似 点击它能够跳转到指定路由

  • 使用时须要导入 能够为其设置一个to属性 值就是单机这个Link时要跳转到路由的path(link 最后会被渲染成a标签展现出来)
  • 所以在开发时尽可能少些a 标签 由于路由不只有 hash 模式仍是 history 模式;写 Link 它会自动根据模式切换路径;
  • 且to的值的这个路由path必须在Route 中注册过才行(只要在应用中注册过便可)

NavLink 和 Link 的做用同样,只不过当前导航激活时(NavLink 的 to 和页面 url 中的路径相同时导航被激活)会给当前被激活的 NavLink 添加一个 active 类名;若是设置 高亮当前激活的导航 给 active 类名添加样式就能够了

二级路由 相似VueRouter 的路由嵌套 直接在须要的地方定义Link 进行路由切换便可

动态路由和路由跳转

-动态路由的路径中有一段是不固定的,/user/detail/:id 这最后一段/:id就不是固定的,通常动态路由是用来页面间传数据的,动态路由也须要在Route中注册css

这样写的是静态路由vue

<Route path='/user/detail' component={Home}></Route>   
复制代码

这样写的是动态路由,它与上面这个不是同一个路由,id是必须项react

<Route path='/user/detail/:id' component={Home}></Route>
复制代码

咱们要跳转到动态路由的时候,后面的id能够直接拼接上去webpack

<Link to={`/user/detail/${item.id}`}>
复制代码

若是咱们须要获取动态路由后面的动态部分,则使用props.match.params属性,值是一个对象,动态部分都被放在里面git

componentWillMount,let { id } = this.props.match.params
复制代码

编程式导航 用代码进行路由的切换

全部的被HashRouter等路由渲染的后代组件的props中都有一个路由信息对象history,其中有一个方法push就是用来切换路由的,参数接受一个路由path this.props.history.push('/home') //构造函数constructor中则是第一个参数propsgithub

路由匹配

路由匹配默认的是模糊匹配 开始匹配上了就匹配上了 多个路由匹配则多个component都会被渲染,很明显这不是咱们想要的,那么就可使用Route的exact关键字让该路由进行精确匹配,以下web

<Route exact path='/home/list' component={list}></Route>
复制代码

这样只有当路由是/home/list的时候才会渲染这个compoent,路由是/home时并不会渲染npm

render 属性 值是一个函数 这个函数要求返回一个jsx对象或者组件

当页面中的url的路径变化时与Route中的path向匹配时,就会执行这个render函数,而后将其返回的jsx或者组件渲染到页面上编程

Switch组件 使用时需导入 当Route匹配一个路由后就不在日后匹配 使用该组件

将全部的Route组件放进Switch组件中去,这样当有一个Route被匹配到后就不会再匹配其余的Route了json

<Switch>
  <Route path='/' exact render={() => <h1>首页</h1>}></Route>
  <Route path='/home' component={Home}></Route>
  <Route path='/login' component={Login}></Route>
  <Route component={NotFound}></Route>
</Switch>

复制代码

设置404 not found页面

只须要写一个没有path的Route就能够了,

<Route component={NotFound}></Route>
复制代码

这样当出现匹配不到的路由就会渲染NotFound组件

create-reat-app建立的项目配置代理

在原来的 create-react-app 脚手架中,是经过 package.json 配置文件来配置代理的。可是,在新版的脚手架中,经过 package.json 只能配置一个代理。若是须要配置多个代理的话,则不能这么干了。

  • 新版的代理配置,是经过 /src/setupProxy.js 这个文件来配置的。 在src下面新建文件setupProxy.js
/ 用来配置代理
const proxy = require('http-proxy-middleware')

module.exports = function(app) {
    app.use(
        proxy(
            '/api', {
                target: 'http://localhost:8888',
                changeOrigin: true,
secure: false
            }
        )
    )
}

配置完以后就能够了,会自动帮咱们引用这个文件

复制代码

受保护的路由 && 自定义菜单激活样式

在真实的项目中,咱们会对一些路由进行保护机制,像有些页面用户没有登陆则不容许访问。vueRouter中有导航守卫来处理这个问题,而在react-router中则须要写受保护的路由来实现 受保护的路由其实说白了就是咱们本身实现一个组件来包裹Route组件,而后使用咱们本身的组件替换掉Route组件,咱们在咱们本身的组件中作逻辑判断

import React, { Component } from 'react'
import { Route, Redirect } from  'react-router-dom'

export default ({component: Component, ...others}) => {
  return <Route {...others} render={(props) => {
  // props 是 router 对象,包含了当前路由的信息
    return localStorage.getItem('loginSystem')
      ? <Component {...props} />
      : <Redirect to={{pathname: '/login', from: props.match.url}} />
  }
  }></Route>
}
复制代码

上面这就是一个受保护的组件,引用以下 import PrivateRoute from './components/Protected'

  • 传一个path和component给咱们写的保护组件(其实就是一个函数组件)中去,保护组件是一个函数组件,咱们传的to以及component都会传进这个函数组件的第一个参数对象中去,咱们直接将其解构而后给component重命名Component(组件首字母大写为了有别于原生标签),拿到component以及其余的to等props放进others对象中,而后保护组件返回一个Route组件,将to等props展开放进Route中,而后为Route设置一个render属性,render是一个方法,参数是router对象,包含了当前路由的信息,咱们在render中作逻辑判断用户是否登陆而后来渲染不一样的组件(render函数须要返回一个jsx对象或者组件,而后在页面的url匹配到当前Route的时候被执行,返回的jsx对象或者组件会被渲染)
  • Redirect是react-router-dom上的一个组件,做用是用来进行重定向的,有一个to属性就是要重定向到的路由path,to的值是一个对象,pathname属性表示重定向的path地址,其余属性会被打成一个location对象传给重定向后的路由组件的props
  • 若是须要用户登陆后还跳转回当前页面呢?
  • 上面render函数的props路由对象中有咱们当前的路由地址,咱们能够经过props.match.url获取到,而后在咱们重定向到登陆页的时候将咱们获取到的地址传过去,而后在用户登陆成功后在经过编程式导航切回来:this.props.history.push(this.props.location.from) 固然咱们也能够用受保护组件来实现其余功能

自定义菜单样式

咱们写vue的时候知道在vue中当导航被激活的时候能够添加router-link-action类样式来当作激活样式,那么在react-router中呢? 仍是使用组件包装来实现 自定义MenuLink组件

import React, { Component } from 'react'

import { Route, Link } from 'react-router-dom'

export default ({ to, label }) => {
  return <Route path={to} children={(props) => {
    return <li className={props.match ? 'active' : ''}>
      <Link to={to}>{label}</Link>
    </li>
  }
  }></Route>
}
复制代码
  • MenuLink组件返回一个Route组件,在Route组件中有一个children属性,属性值依旧是一个方法,方法的参数props也是当前路由信息对象,咱们在其中判断当前路由是否被激活,怎么判断?

  • 若是路由被激活则当前路由对象中的match属性是一个对象,若是没有被激活这match属性是null,咱们就经过这个来判断,若是激活了就为其添加active类名,没激活就不添加,active类名就是咱们定义的选中时样式

  • children 和 render的区别: 虽然值都是一个函数,返回的都是一个jsx对象或者组件 render在页面的url与当前Route匹配时被调用,将返回jsx对象或者组件渲染 children则是无论页面你的url和当前Route是否匹配都会被调用,返回的jsx对象或者组件会被渲染

  • 其实套路都是同样的,就是使用咱们的组件将Route包裹起来,在咱们的组价中作逻辑判断而后选择性的返回一个Route组件出来

antd(Ant Design )按需引入以及使用

中文文档:ant.design/docs/react/…

antd按需引入

  • create-react-app搭建的项目中按需引入antd以及配置Less

  • 使用creat-react-app搭建的项目中的webpack文件是隐藏起来的 暴露wenpack文件的指令是yarn eject. 在使用这个指令以前要先推送一次git文件才行,或者删除git文件

  • 运行以后会询问是否暴露,输入y便可。

  • 此时在项目目录下会多出一个config文件夹。

  • 按需引入antd:

  • 安装babel-plugin-import npm i babel-plugin-import -sava

  • 在根目录下的package.json下的bable中添加相应代码便可 "babel": { "presets": [ "react-app" ], "plugins": [ [ "import", { "libraryName": "antd", "style": "css" // 引入样式为 css // style为true 则默认引入less } ] ] }

  • 而后就能够直接使用import { Button } from 'antd'来按需引入的,不须要先引入全局的import 'antd/dist/antd.css'再引入import Button from 'antd/es/button';

  • 配置less creat-react-app搭建的项目中默认没有为咱们配置less,若是想用less须要本身配置,也要先使用npm run eject暴露出配置文件来 安装less: npm i less less-loader -save

  • 在暴露出来的webpack中找到webpack.config.js文件,须要首先在上面的一大堆cosnt常量定义中加入 const lessRegex = /.less/;
const lessModuleRegex = /\.module\.less/; 这是用来识别less的

而后在其module的rules中添加以下代码: { test: lessRegex, exclude: lessModuleRegex, use: getStyleLoaders( { importLoaders: 2, sourceMap: isEnvProduction && shouldUseSourceMap, }, 'less-loader' ), // Don't consider CSS imports dead code even if the // containing package claims to have no side effects. // Remove this when webpack adds a warning or an error for this. // See github.com/webpack/web… sideEffects: true, }, { test: lessModuleRegex, use: getStyleLoaders( { importLoaders: 2, sourceMap: isEnvProduction && shouldUseSourceMap, modules: true, getLocalIdent: getCSSModuleLocalIdent, }, 'less-loader' ), },

相关文章
相关标签/搜索