[Vue] Vue router routing management

Time:2021-10-19

Vue router routing management

  1. Basic use
  2. Advanced

1 Foundation

  1. Installation and basic use
  2. Dynamic routing
  3. Nested Route
  4. Programming navigation
  5. Named route
  6. Named view
  7. Redirection and alias
  8. Routing component parameters
  9. History mode
  10. Modules

1.1 installation and basic use

//Installation
npm install vue-router --save
//Introduced in main.js
import VueRouter from 'vue-router'
Vue.use(VueRouter)
//At this time, there will be two more attributes ` $route 'and ` $router' on the Vue instance

Create two pages

//About.vue
<template>
  < div > About page < / div >
</template>
//Detail.vue
<template>
  < div > About page < / div >
</template>

Configure routing

//Router.js file
import VueRouter from "vue-router";
import About from './pages/About'
import Detail from './pages/Detail'

export const router = new VueRouter({
    routes: [
        {
            path: '/about',
            component: About,
        },
        {
            path: '/detail',
            component: Detail
        }
    ]
})
  • Introduce vuerouter, instantiate it, and import components
  • Configuration objectroutesOptions toArray objectformRegister routing, including paths and components

Introduce the router instance in mian.js and register it

//mian.js
import { router } from './router'

new Vue({
  router,
  render: h => h(App),
}).$mount('#app')
//At this time, you can observe the related configurations of $route and $route

Use routing in app.vue

<template>
  <div id="app">
    < router link to = "/ about" > jump to about < / router link > < br / >
    < router link to = "/ detail" > jump to detail < / router link >
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: "App",
};
</script>

router-linkFor routingentrance, configure the path in to
router-viewFor routingExport, the jump page is displayed here
be similar toDynamic component, the basic jump function is realized, and the routing function is more powerful
$router is similar to $store. After the root instance is registered,SubcomponentsCan access the originalRouting instance, there is no need for frequent introduction in sub components$ Route is the current route

1.2 dynamic routing

Jump to the same component according to different path parameters and display different data

//router.js
{
    path: '/about:id',
    component: About,
},
//App.vue
<template>
  <div id="app">
    < router link to = "/ about /: '1'" > user 1 < / router link > < br / >
    < button @ Click = "to" > User 2 < / button >
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: "App",
  methods: {
    to() {
      this.$router.push('/about/:"2"');
    },
  },
};
</script>
//About.vue
<template>
  < div > About page {{userid}} < / div >
</template>

<script>
export default {
  computed: {
    userId() {
      return this.$route.params.id;
    },
  },
};
</script>
  • Add path registered in router:param
  • You can use router link or $router.push to jump. The path carries parameters
  • The parameters of the dynamic path can be accessed through $route.params on the route to jump to

    You can request data to render the page according to the parameters

  • :The params parameter is defined correspondingly
  • ? = &, you can define query parameters, which can be accessed through $route. Query

    < router link to = "/ about /? Id = 1" > user 1 < / router link > < br / >

wildcard
Capture all routes or 404 not found routes

{// match all paths
    path:'*'
}
{// match any path starting with '/ user'
    path:'/user-*'
}

When using wildcard routing, $route.params adds a parameter named pathmatch. Contains parts of the URL that match wildcards

//router.js
{
    path: '*',
    component: () => import('./pages/Notfound')
}

When the jump path fails to match, you can match the wildcard path andpathMatchParameter indicates the wrong path
Use ‘/ user – *’ to set the prompt information that a page is not found in a specific path

1.3 nested routing

Sometimes a route jump may be required after a route jump. In this case, multi-level routes need to be nested
Add at route registrationchildrenattribute

//router.js
{
    path: '/about',
    component: About,
    children: [
        {
            path: 'child',
            component: () => import('./pages/Child')
        }
    ]
},
//Jump
< router link to = "/ about / child" > Level 2 jump < / router link >

Not required before the path of the sub route/Otherwise, it will be considered to start with the path

1.4 programmed navigation

In addition to using router linkDeclarativeYou can create a tag to jump, or you can use the instance method of routerProgrammingRealize jump
push: add history stackadd toFor a new record, you can click the browser’s back to the previous URL
replacereplaceCurrent history stack top record
go(n): forward or backward | n | steps. Negative number means backward, positive number means forward. If the record is not enough, it will fail

this.$router.push({
  path: "/detail",
  // params: { userId: 123 },
  Query: {user: "Zhang San"},
});

The data in push can be usedObject form, params parameterNoAnd pathSimultaneous use, in router linktoIt also supports writing in the form of objects
have access tonameProperty to pass params parameter

  • paramsParameters:muststayrouteAdd a parameter name to the and use it when jumpingnameattribute
  • queryParameter: it is not necessary to register inrouteAdd information on, use when jumpingPath or nameAll can

    If a parameter is added to the path, but the params parameter is not passed during the jump, the jump will also fail
    When using the name attribute, params and query parameters can be passed at the same time

1.5 named routes

Name has been introduced above, which is the naming of routes
It can simplify the problem of long path and avoid the problem of params parameters

routes: [
  {
    path: '/user/:userId',
    name: 'user',
    component: User
  }
]

1.6 named views

Router view can be addednameProperty, corresponding to the component in the route
When registering a route, the components can be in the form of objects, including multiple components. The key is provided to name for selection

//router.js
{
    name: 'detail',
    path: '/detail/:userId',
    components: {
        default: Detail,
        a: () => import('./pages/Ads')
    }
},
//View
<router-view></router-view>
<router-view name="a"></router-view>

View without name attribute, usedefaultComponents of

1.7 redirection and aliases

redirect
Access’ / a ‘redirect’ / B ‘, replace the URL and matching route with’ / B ‘

//Path
routes: [
  { path: '/a', redirect: '/b' }
]
//Naming
routes: [
  { path: '/a', redirect: { name: 'foo' }}
]
//Dynamic method
routes: [
  { path: '/a', redirect: to => {
    //Method receives the destination route as a parameter
    //Return redirected string path / path object
  }}
]

You can redirect the root path to the sub route path when returning to the home page to ensure the filling of the page

alias
Alias’ B ‘of’ / a ‘. When accessing’ / B ‘, the URL is still’ / B ‘, but the route matching is’ / a’, which is equivalent to accessing ‘/ a’, but the name is different

routes: [
  { path: '/a', component: A, alias: '/b' }
]

The UI structure can be freely mapped to any URL, and the nested routing structure with configuration is not limited

1.8 routing component transmission parameters

propsAttribute: Boolean | object | function
$route will make the component highly coupled with the corresponding route, so that the component can only be used on a specific URL, limiting flexibility.
The props property allows you to route components anddecoupling

//Object form
{
    name:'detail',
    path:'/detail',
    component:Detail,
    props:{foo:'a',bar:'b'}
}

In detailIn component, you can directlyDeclared in propsPost use
Static data is transmitted in the form of objects, which is written during configuration, and there are few usage scenarios

//Boolean form
{
    ...
    props:true,
}
//Multi component
{
    ...
    components:{Detial,Ads},
    props:{Detail:true,Ads:false}
}

When jumping a routeparamsParameters are passed into the component and used after they are declared in the props of the component

//Function form
{
    ...
    props($route){
        return {
            id:$route.params.userId,
            name:$route.query.user
        }
    }
}
//Deconstruction assignment abbreviation - similar to the context object in vuex's action
{
    ...
    props({params,query}){
        return {
            id:params.userId,
            name:query.user
        }
    }
}

When props is not used, all the parameters passed are on the URL, which needs to be obtained one by one using calculation properties
Using the function form of props, params, query parameters and static data can be declared in props in the component
In this way, the operation of value selection is simplified and decoupled

1.9 history mode

Configuration in routerroutesIn addition to options, there are other options, such asmode
Mode is hash by default, and there will be one in the address bar#No. when the URL changes, the page will not be reloaded
Change to normal URL form, usemode:'history'
The history pattern requires someBackground support, or 404 will appear

This is because the address in # the hash mode will jump as a route and will not initiate an HTTP request. However, in the history mode, an HTTP request will be initiated when refreshing the page. Because there is no # separation, the entire address will be used as the request address
nginx

location / {
  try_files $uri $uri/ /index.html;
}

Node.js

const http = require('http')
const fs = require('fs')
cosnt httpPort = 80

http.createServer((req,res)=>{
    fs.readFile('index.html','utf-8',(err,content)=>{
        if(err){
            ...
        }
        res.writeHead(200,{'Content-Type':'text/html;charset=utf-8'})
        
        res.end(content)
    })
}).listen(httpPort,()=>{
    console.log('Server listening on:http://loaclhost:%s',httpPort)
})

It can be used in node.jsconnect-history-api-fallbackPlug in to quickly resolve the conflict between the back-end address and the front-end routing address in history mode, resulting in request failure

2.10 Modules

When there are too many levels of nested routing, it can be divided into multiple modules
Similar to the vuex splitting method, you do not need to create a module array. After importing, you can directly register in the routes array

//Index.js entry file in the routes folder
import VueRouter from 'vue-router'
import { about } from './modules/about'
import { detail } from './modules/detail'
import { Notfound } from './Notfound'

export const router = new VueRouter({
    routes: [
        { path: '/' },
        about,
        detail,
        Notfound
    ]
})

After the modification to modularization, it needs to be re introduced and registered in main.js

2 Advanced

  1. Routing guard
  2. Routing meta information
  3. Transition dynamic effect
  4. Data acquisition
  5. Rolling behavior
  6. Route lazy loading
  7. Navigation fault

2.1 route guard

  1. Global front guard
  2. Global resolution guard
  3. Global post hook
  4. Route exclusive guard
  5. Guard in assembly
  6. Overall process

2.1.1 global front guard

beforeEach

const router = new VueRouter({})
router.beforeEach((to,from,next)=>{})
  • To: destination route
  • From: route to leave
  • Next: release function,No parametersJump directly to the destination route

    • Next (false) interrupts the current navigation
    • Next (‘/’) or next ({path: ‘/’}) specifies the route jump, which can be usednameAnd other options
    • Next (error) interrupts the current navigation and passes the error instance into router. Onerror() to execute callback
    • The next function can only be called once
//Index.js - simulate an unlisted user accessing the page and redirect to the login page
router.beforeEach((to, from, next) => {
    if (to.name !== 'login' && to.name !== 'register' && !isAuthenticated) {
        next({ name: 'login' })
    } else {
        next()
    }
})

If you jump to the push mode used, an error will be reported after being intercepted and reset by the guard, but the use will not be affected
Catch can be used to catch errors after push

2.1.2 global resolution guard

beforeResolve
Similar to beforeeach
Difference: before the navigation is confirmed, at the same timeGuard in assemblyandAsynchronous routing componentAfter being parsed, the parsing guard is called

2.1.3 global post hook

afterEach
Unlike the guard, there is no next release function

router.afterEach((to, from) => {
  // ...
})

2.1.4 route exclusive guard

beforeEnter
The difference from the global routing is that it controls a route separately as a configuration item of a route

routes: [
  {
    path: '/foo',
    component: Foo,
    beforeEnter: (to, from, next) => {
      // ...
    }
  }
]

To: jump to the current route
From: jump from a route

You can limit where from can jump to this route

2.1.5 guards in components

As a configuration in a componentoption
BeforeRouteEnter: similar to the exclusive guard, before the component instance is created, it is not possible to get the VM instance.

You can add a callback function in next to access the component instance

beforeRouteEnter (to, from, next) {
  next(vm => {
    //Accessing component instances through 'VM'
  })
}

Beforerouteupdate: called when the path changes and the component is reused, you can access the VM instance

This represents the routing component instance from

Beforeroutleave: called when leaving the corresponding route of the component to access the VM instance of the component

You can judge the contents of the component before leaving to confirm whether to leave

2.1.6 overall process

[Vue] Vue router routing management

2.2 routing meta information

Meta configuration item, which stores routing meta information
In the continuous route nesting, the route information of each layer will be collected to $route.matchedarrayin
You can use the array traversal method to traverse the matched array to check the meta field

router.beforeEach((to, from, next) => {
  if (to.matched.some(record => record.meta.requiresAuth)) {
    // this route requires auth, check if logged in
    // if not, redirect to login page.
    if (!auth.loggedIn()) {
      next({
        path: '/login',
        query: { redirect: to.fullPath }
      })
    } else {
      next()
    }
  } else {
    Next() // make sure to call next()
  }
})

2.3 transition dynamic effect

Router view is a basic dynamic component, which is equivalent to the component tag
So you can wrap it with the transition tagtransitioneffect
Similarly, keep alive is used to implement componentscache
Transition and keep alive

2.4 data acquisition

The route jump is often accompanied by obtaining data from the server
Request after navigation: after navigation, request data in the declaration cycle hook of the component. The load prompt is displayed during request completion.

Use V-IF conditional rendering to load pages, error pages, and request success pages
Request data in the created hook

Request before navigation is complete: get the data in the route guard and execute navigation after successful acquisition

Request data in beforerouteenter, in next()CallbackData obtained from configuration request in

2.5 rolling behavior

Scrollbehavior configuration options
When switching to a new route, the page scrolls to the top or maintains the original scrolling position

const router = new VueRouter({
  routes: [...],
  scrollBehavior (to, from, savedPosition) {
    //Return where do you want to scroll
  }
})

By default, no scrolling occurs. When returning to svaedposition, the forward / backward operation is consistent with the browser’s native operation

return {
    x:0,y:0
}

Scroll directly by coordinates

meta:{x:0,y:0}
return {
    selector:to.meta,
    behavior:'smooth'
}

According to meta informationSmooth scrolling

return new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve({ x: 0, y: 0 })
  }, 500)
})

You can return a promise and pass in the scroll information in resolve to realizeAsynchronous scrolling

2.6 routing lazy loading

Asynchronous component

//Asynchronous component factory function
const AsyncComponent = (url) => ({
  //Component to be loaded (it should be a 'promise' object)
  component: import(url),
  //Components used when asynchronous components are loaded
  loading: LoadingComponent,
  //Components to use when loading fails
  error: ErrorComponent,
  //Show the delay time of the component when loading. The default value is 200 (milliseconds)
  delay: 200,
  //If a timeout is provided and the component load times out,
  //The component used when the load failed is used. The default value is: ` infinity`
  timeout: 3000
})

Using the import () function to import components asynchronously, you can not download some components at the first rendering
Download when accessing asynchronous components

2.7 navigation fault

When route navigation fails, the error message can be processed in a chain after push

  • isNavigationFailure(failure,NavigationFailureType)
  • NavigationFailureType

    • Redirected: called next (newlocation) to redirect to another place
    • Aborted: next (false) was called to interrupt this navigation
    • Cancelled: there is a new navigation before the current navigation is completed
    • Duplicated: navigation is blocked because we are already at the target location
import VueRouter from 'vue-router'
const { isNavigationFailure, NavigationFailureType } = VueRouter

//Attempting to access admin page
router.push('/admin').catch(failure => {
  if (isNavigationFailure(failure, NavigationFailureType.redirected)) {
    //Display a small notification to the user
    showToast('Login in order to access the admin panel')
  }
})
//Attempting to access admin page
router.push('/admin').catch(failure => {
  if (isNavigationFailure(failure, NavigationFailureType.redirected)) {
    failure.to.path // '/admin'
    failure.from.path // '/'
  }
})