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
pathname
Absolute path of the current routesearch
Query parameters, access/user? userId=123
= > can be got? userId=123
hash
:#the-hash
state
: Routing meta information similar to vUEmeta
The information stored here is not displayed in clear text on the browser
match
params
when<Route to='/user/:id'/ component={user}>
To access/user/123
inuser
Component.this.props.match.params.id
You can get the IDisExact
Is 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 replacedthis.$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 backthis.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!