preface

Compare the similarities and differences between vue-router and React-router, so as to better remember the knowledge of both

use

vue

The installation

npm install vue-router
Copy the code

Apply it to man.js

import Vue from "vue"
import VueRouter from "vue-router"
Vue.use(VueRouter)
//1. Define routes
let routes = [
  {
    path:'/home'.name:'home'.// Name the route,
		component:Home,
    meta: {info:'123'}// Route meta information
  },
  {
    path:'/login'.component:Login
  }
]
//2. Create a route instance
let router = new VueRouter({
  routes
})
//3. Mount routes to the root instance
const app = new Vue({
  router
}).$mount('#app')
Copy the code

react

The installation

npm install react-router-dom
Copy the code

use

import {BrowserRouter,Route} from "react-router-dom"
function App(props){
  returnWrap a BrowserRouter or HashRouter <BrowserRouter> <Route Path = around it'/home' component={Home}></Route>
      <Route path='/login' component={Login}></Route>
    </BrowserRouter>
  )
}
Copy the code

The Link tag

vue

<router-link to='/path'<router-link :to= <router-link :to="{path:'/path'}"> Jump link </router-link> // Named route equivalent /user/123 <router-link :to="{name:'user',params:{ userId:123 }}"></router-link> // with query parameters equivalent to /user? name=cat <router-link :to="{name:'user',query:{name:'cat'}}"></router-link> // Replace attributes use router.replace and not router.push <router-link to="/path" replace></router-link>
Copy the code




When clicked, the tag is added by default. Router-link-active class name, based on which you can add click styles

react

import {Link} from "react-router-dom"
function App(props){
  return (
    <Link to='/path'> Jump Link </Link> // equivalent /path? name=cat# the - the hash in the component can be through this. Props. The location. The state for the state of the Link
    <Link to={{pathname:'/path',search:'? name=cat'.hash:'#the-hash',state:{info:'123'}}} > < / Link > / / func = > < Link to return object = {location = > ({... location,pathname:'/path'})} > < / Link > / / func = > returns a string < Link to = {location = > `${location.pathname}? name=cat`}></Link> // replace <Link to='/path'Replace > Link </Link>)}Copy the code

Link does not have an active attribute. To have an active attribute, use

import {NavLink} from "react-router-dom"
function App(props){
  return (
    <NavLink to='path' activeClassName='Active state class name'></NavLink>
    <NavLink to='path' activeStyle={{color:'red'}}></NavLink>
  )
}
Copy the code

The view components

View component, solve the problem of where the component is rendered when matching to the route

vue


renders the view component that the path matches

// app. vue <template> <div> I am the App component <router-view></router-view> </div> </template> // user.vue <template> <div> I am the user component <router-view></router-view> </div> </template> // name.vue <template> <div> I am the name component </div> </template> // routes <script> const router = new VueRouter({ routes:[ { path:'/user',
        component:user,
        children:[
          path:'/user/name',
          component:name
        ]
      }
    ]
})
</script>
Copy the code

When the route matches /user, the user component is rendered to the router-view location in app.vue

When the path matches /user/name. The location where the name component renders to the router-view in user.vue and the uer component renders to the router-view in app. vuew

Named views can be used when a route renders multiple components

<router-view class='view one'></router-view>
<router-view class='view two' name='a'></router-view>
<router-view class='view three' name='b'></router-view>
<script>
const router = new VueRouter({
    routes:[
      {
        path:'/', components:[// remember adding s default:componentOne, a:componentTwo, b:componentThree]}]}) </script>Copy the code

react


is responsible for matching routes. It is responsible for the rendering location of the Route view. Where is

, the component is rendered


Three ways to render components

<Route component={Home}></Route>// Children ={Home}></Route> <Route><Home></Home></Route>// same as above, regardless of whether there is a match, will renderCopy the code
/ / value is [history,loacation,match] <Route render={value=><Home {... value}></Home>}></Route>Copy the code

The Children method overrides component and Render

Children render regardless of route match, render and Component only render if route match

Route objects

vue

This.$route gets the route object in the component

  • $route.path Absolute path /user/name of the current route

  • $route.params gets the parameters of the dynamic route

    Path :’/user/:id’; this.$route.params.id = ‘123’

  • $route.query Retrieves query parameters

    Access/user? Name =123; this.$route.query.name =123

react

In React, to get a routing object, you must withRouter the component

function App(props){
  return (
  	<Route path='/home' component={Home}></Route>
  )
}
// Home.jsx
import {withRouter} from "react-router-dom"
class Home extends Component{
  render() {return <div>home</div>
  }
}
export default withRouter(Home)
Copy the code

Only the withRouter, props of the Home component can have history,location, and match objects

  • history
    • action, the operation of the routing stack can be known asPOP.PUSH.REPLACE
  • location
    • pathnameAbsolute path of the current route
    • searchQuery parameters, access/user? userId=123= > can be got? userId=123
    • hash:#the-hash
    • state: Routing meta information similar to vUEmetaThe information stored here is not displayed in clear text on the browser
  • match
    • paramswhen<Route to='/user/:id'/ component={user}>To access/user/123inuserComponent.this.props.match.params.idYou can get the ID
    • isExactIs the current route a complete match

Programmatic navigation

vue

$route is the route object, and $router is the mount method

  • this.$router.push('/path')
  • this.$router.push({path:'/path'})
  • this.$router.push({name:'user',params:{id:123}})equivalent/user/123
  • this.$router.push({name:'user,query:{name:'123'}'})equivalent/user? name=123
  • this.$router.replace()As above, no new route is added to the routing stack, only the current route is replaced
  • this.$router.go(1)Go one step further, equalhistory.forward()
  • this.$router.go(-1)Take a step back

react

  • this.props.history.push('/user',{info:123}), the first parameter path, and the second parameter state(similar to vUE routing meta-information)
  • this.props.history.replace(path,state)
  • this.props.history.go(n)equivalentvuerouter
  • this.props.history.goBack()The browser takes a step back
  • this.props.history.forForward()Browser Ahead

Global navigation guard

Used to protect pages that require permissions to access

vue

import Vue from "vue"
import VueRouter from "vue-router"
Vue.use(VueRouter)
let router=new VueRouter({
  routes:[
    {
      path:'/login'.component:Login
      name:'login'
    },
    {
      path:'/home'.component:home,
      name:'home'
    },
    {
      path:'/user'.name:'user'
      component:User
    }
  ]
})
// Route whitelist, pages that can be accessed without permission
let whiteList = ['/login'.'/home']
// Global front-navigation guard, which is called before every jump
router.beforeEach((to,from,next) = >{
  // To is the routing object to be accessed
  // From is the route object to leave
  // The access path is whitelisted and allowed to jump
  if(whitelist.includes(to.path){
     next()// Remember to next()
  }else{
    if(isLogin)// If you have logged in, let it jump
      next()
    }else{
      next('/login')// The login page is displayed if there is no login}}})Copy the code

react

In routing component, enclosing props. History. Listen (fn) can monitor the change of route, we can in the routing with components, listening routing change, make corresponding jump

// App.jsx
function App(){
  <BrowserRouter>
  	<RouterGuard></RouterGuard>
  </BrowserRouter>
}
// RouterGuard.jsx
import {withRouter,Route} from "react-router"
class RouterGuard extends Component{
  whilteList=['/login'.'/home']
  componentDidMount() {this. Unlisten = this. Props. Histroy. Listen ((the location, action) = > {/ / location is routing object, the action is how operation routing of the stacklet{ pathname } = location; // The access path is not whitelisted and there is no loginif(! this.whiteList.includes(pathname)&&! isLogin){ this.props.history.replace('/login')}}); } // When the component is uninstalled, unlistencomponentWillUnmount() {
    this.unlisten();
  }
  render() {return<> // Write the Route <Route path='/home'component={home}></Route> ... // Also use the method getRoue() </>)}} which will be used belowexport default withRouter(RouterGuard)
Copy the code

React Emulates the way vUE configures routes

// routerConfig.js
import Login from './view/Login';
import Home from './view/Home';
import Root from './view/Root';
let routes = [
	{
	    path: '/'.component: Root,
            children: [{path: '/login'.component: Login,
            	},
            	{
            		path: '/home'.component: Home,
            	},
            ],
	},
];
// Convert route path to absolute path
routes.forEach(item= > {
	if (item.children) {
		item.children.map(child= > {
			if(! child.path.startsWith('/')) { child.path = item.path + child.path; }}); }});export default routes
Copy the code

Write a component that traverses routes and returns the

component

functionGetRoute (routes){//1. Check whether routes is arrayif(! Array.isArray(routes)){returnnull; } // Iterate over routesletRoutesDom = routes.map((item,index)=>{routesDom = routes.map((item,index)=>let{children,component:Component,render,.. rest} = item;return<Route key={index} {... Rest} render={value=>{// value is [history,location,match, etc. <Component {... Children {getRoute(children)} </Component>}}/>})return<Switch>// The Switch component guarantees that only one route (from top to bottom) {routesDom} </Switch>}export default withRouter(getRoute)
Copy the code

use

function App(){
  return (
    <BrowserRouter>
    	<getRoute></getRoute>
    </BrowserRouter>
  )
}
Copy the code

Routing meta information

Use the routing meta information to set the title of the page

vue

import Vue from 'vue'
import VueRouter from "vue-router"
Vue.use(VueRouter)
let router = new VueRouter({
  routes:[
    {
      path:'/home'.component:Home,
      meta: {title:'home'}// Route meta information is not displayed in plain text on the browser
    }
  ]
})
router.beforeEach((to,from,next) = >{
  let title = to.meta.title
  document.title=title
})
Copy the code

react

Set location.state in the component

This. Props. Location. State = {title: 'front page'}

// Listen for route changes in the root component
componentDidMount(){
  this.unlisten = this.props.history.listen((location,action) = >{
    const {title}=location.state
    document.title=title
  })
}
componentWillUnmount(){
  this.unlisten()
}
Copy the code

Route jump block

When a user enters content in an input on a page and is about to jump to the page before saving it, the route should be blocked

vue

Navigation guard, component exclusive interceptor

beforeRouteLeave(to, from, nexxt) {
  const allowTransition = window.confirm('Sure to jump? ')
  if (allowTransition) {
    next()// Continue to jump
  } else {
    next(false)// Cancel the jump}},Copy the code

react

componentDidMount(){this.unblock = this.props.history. Block ((localtion,action)=>{// location is the route object to jump toreturn 'leave? '})} // Unlisten when the component is destroyedcomponentWillUnmount() {
	this.unblock();
}
Copy the code

If you want to customize the prompt,

<BrowserRouter
  getUserConfirmation={(message, callback) => {
    // this is the default behavior
    //const allowTransition = window.confirm(message);
    //callback(allowTransition);Message is the message passed by history.block and when you get the message, you can customize modal to pop up to get the user's action callback(Boolean)// True indicates a jump, false indicates no jump}} / >Copy the code

conclusion

Author: Hu Zhiwu

Time: 2020/05/21

If there are any mistakes or omissions in the article, please correct them. If you think it is well written, please give a thumbs-up!