Vue Router is the official route of vue.js. It is deeply integrated with the vue.js core, making it a breeze to build single-page applications with vue.js. With the release of VUe3, Vue Router has also been updated to version 4.x to accommodate the new features of VUe3. This article is based on Vue Router4.

Vue Router

1. Installation and configuration

Run NPM install vue-router@4. After the installation is complete, create SRC /router/index.js in the directory and write the following configuration:

import { createRouter, createWebHashHistory } from 'vue-router'
import Layout from '@/layout/index.vue'
import Home from '@/views/home/Home.vue'
const routes = [
  {
    path: '/'.component: Layout,
    children: [{ path: ' '.component: Home }],
  },
]

export default createRouter({
history: createWebHashHistory(),
routes,
})
Copy the code

Used in the main. Js

/ /... +
import router from './router/index'
createApp(App).use(router).mount('#app')
Copy the code

Tips: Use the createWebHashHistory method for Hash mode and createWebHistory method for History mode.

2. Dynamic route matching

  • The routing configuration
{ path: '/courseinfo/:title'.component: CourseInfo }
Copy the code
  • Two ways to jump
  <router-link :to="{ path: '/courseinfo/c' }">The C language details page is displayed</router-link>
Copy the code
import { useRouter } from 'vue-router';

const router = useRouter();
function toInfo() {
  router.push({ path: '/courseinfo/python'})}Copy the code
  • How to get parameters$route.params.titleYou can only use or in templatesuseRoute().params.titleMust be called in setup. becausesetupCannot use this, so$routeThis can only be used in templates.
  • Response parameter variation: When using a route with parameters, note that when the user from/courseinfo/javascriptNavigate to the/courseinfo/pythonWhen,The same component instance will be reused. Because both routes render the same component, reuse is more efficient than destroying and recreating.However, this also means that the component’s lifecycle hooks are not called. Solution: Watch$routeAny property on the object, in this case, is$route.params; Or use the navigation guard.
  • Capture all routes or 404 Not found routes
const routes = [
  // Everything will be matched and placed under '$route.params.pathMatch'
  { path: '/:pathMatch(.*)*'.name: 'NotFound'.component: NotFound },
  // Will match everything starting with '/user-' and place it under '$route.params.afteruser'
  { path: '/user-:afterUser(.*)'.component: UserGeneric },
]
Copy the code

Programmatic navigation

declarative programmatic
<router-link :to="..." > router.push(...)

Common use

/ / transfer path
router.push(`/user/${username}`)
/ / or
router.push({ path: `/user/${username}` })
Copy the code

After routing

A router/index.js is required for route definition and can be redirected based on the name value

{ path: '/courseinfo/:title'.component: CourseInfo, name: 'CourseInfo' },
Copy the code

Navigation time pass reference

Params mass participation

// Use 'name' and 'params' to take advantage of automatic URL encoding; 'path' and 'params' cannot be used together
router.push({ name: 'user'.params: { username } }) 
Copy the code

Query passes the parameter to the user page. The link is /user? $route.query.data =123; $route.query.data =123

router.push({ name: 'user'.query: { data:123}})Copy the code

router.replacemethods

Much like router.push, the only difference is that it does not add a new record to history, but replaces the current history record with its method name.

declarative programmatic
<router-link :to="..." replace> router.replace(...)

router.go(n)methods

router.go(-1)  // Take a step back
Copy the code

4. Route guard

Global guard

  • Maximum range, and any route navigation triggers a callback
const router = createRouter({ ... })

router.beforeEach((to, from) = > {
  // ...
  // Return false to cancel navigation
  return false
})
Copy the code

To: the destination to be entered, from: the route to be left

  • Optional third parameternext

For example, if the route guard is used to verify login permission, the login page is displayed if the user has logged in to the login page. src/permission.js:

router.beforeEach((to, from, next) = > {
  if (to.path === '/loginsuccess') {
    if (localStorage.getItem('isLogin')) {
      next();
    } else {
      next({ path: '/login'}); }}else{ next(); }});Copy the code

According to the localStorage cache, you can manually clear the switchover status to debug and observe the result.

Route exclusive guard

You can define beforeEnter guards directly on the route configuration:

  // src/router/index.js
  {
    path: '/loginsuccess'.name: 'LoginSuccess'.component: LoginSuccess,
    beforeEnter: (to, from) = > {
      console.log("---- route exclusive guard for successful login page")}},Copy the code

BeforeEnter guard fires only when entering a route, not when params, Query, or hash changes. For example, go from /users/2 to /users/3 or from /users/2#info to /users/2#projects. They are triggered only when navigating from a different route.

Intra-component route guard

  • beforeRouteEnter
  • beforeRouteUpdate
  • beforeRouteLeave
const UserDetails = {
  template: `... `.beforeRouteEnter(to, from) {
    // called before the corresponding route to render the component is validated
    // Cannot get component instance 'this'!
    // Because the component instance has not yet been created when the guard executes!
  },
  beforeRouteUpdate(to, from) {
    // Called when the current route changes but the component is being reused
    // For example, for a path with dynamic parameters' /users/:id ', when jumping between '/users/1' and '/users/2',
    // Since the same 'UserDetails' component is rendered, the component instance is reused. And the hook will be called in that case.
    // Because the component is already mounted by the time this happens, the navigator can access the component instance 'this'
  },
  beforeRouteLeave(to, from) {
    // called when the navigation leaves the corresponding route rendering the component
    // Like 'beforeRouteUpdate', it can access component instance 'this'}},Copy the code

When used in setup, update and Leave guards can be added via onBeforeRouteUpdate and onBeforeRouteLeave, respectively. Tip: Setup does not provide an equivalent method for beforeRouteEnter.

5. Route meta information

Additional information is added by adding a META field when defining a route configuration. SRC /permission.js is rewritten to use meta routing meta information to determine whether to jump to the login success page or log in

router.beforeEach((to, from, next) = > {
  if (to.meta.auth) {
    if (localStorage.getItem('isLogin')) {
      next();
    } else {
      next({ path: '/login'}); }}else{ next(); }});Copy the code

6. Lazy route loading

During packaging, single routing components are fragmented and loaded asynchronously only during access, which can effectively reduce app size and loading time. src/router/index.js

const Login = () = > import('@/views/login/Login.vue');

const routes = [
    { path: '/login'.name: 'Login'.component: Login }
]
Copy the code

7. Use in Composition API

You can’t access this in the composite Api and setup, you can’t use this.$router, etc. New functions have been added to access router routes, navigation hooks, etc.

  • UseRouter and useRoute
<script setup>
import { useRouter, useRoute } from 'vue-router'

const router = useRouter()
const route = useRoute()
/ /...
</script>
Copy the code
  • Route guard hook
<script setup>
import { onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router'

// Equivalent to beforeRouteLeave, but without access to 'this'
onBeforeRouteLeave((to, from) = > {})

// Equivalent to beforeRouteUpdate, but without access to 'this'
onBeforeRouteUpdate((to, from) = > {})

</script>
Copy the code

8. Dynamic routes

Sometimes routes need to be added or removed while the program is running. In this case, you can use the following method.

  • New routing
const TestRoute = () = > import('@/views/vuerouter/TestRoute.vue');

  router.addRoute({
    path: '/testroute'.component: TestRoute,
    name: 'TestRoute'});Copy the code
  • Remove the routing
// Delete by name
router.removeRoute('TestRoute');
Copy the code
// Second way: automatic overwrite when the name is repeated
router.addRoute({ path: '/about'.name: 'about'.component: About })
// This will delete previously added routes because they have the same name and the name must be unique
router.addRoute({ path: '/other'.name: 'about'.component: Other })
Copy the code
  • To add a nested route, pass the parent route name by parameter 1
router.addRoute('parentRouteName', {... })Copy the code
  • Search for an existing route

Router.hasroute () : checks whether a route exists. Router.getroutes () : Gets an array of all routing records.

9. Cache and transition animations

The cache

<router-view v-slot="{ Component }">
    <keep-alive>
        <component :is="Component" />
    </keep-alive>
</router-view>
Copy the code

When switching back and forth to save component state, you can wrap dynamic components with

in combination with V-slot API, and the component instance is cached.

Transition animations

  • The basic use

src/layout/AppMain.vue

    <router-view v-slot="{ Component }">
      <transition name="fade" mode="out-in">
        <component :is="Component" />
      </transition>
    </router-view>
Copy the code

All of the Transition features apply here, too. Let’s define CSS animations

.fade-enter-active..fade-leave-active {
  transition: opacity 0.5 s ease;
}

.fade-enter-from..fade-leave-to {
  opacity: 0;
}
Copy the code
  • Single route animation

Add meta routing meta information. Special transition animations are required through meta Settings

{ path: ' '.component: VuerouterPage, meta: { transition: 'slide'}},Copy the code

AppMain.vue

    <router-view v-slot="{ Component, route }">
      <transition :name="route.meta.transition || 'fade'" mode="out-in">
        <component :is="Component" />
      </transition>
    </router-view>
Copy the code
/* Slide Transition from left to right */
.slide-enter-active..slide-leave-active {
  transition: 0.5 s ease;
}

.slide-enter-from {
  transform: translateX(-50px);
  opacity: 0;
}
.slide-leave-to {
  transform: translateX(50px);
  opacity: 0;
}
Copy the code
  • Dynamically determine the animation type based on the relationship between routes
<router-view v-slot="{ Component, route }">
    <transition :name="route.meta.transition">
        <component :is="Component" />
    </transition>
</router-view>
Copy the code
router.afterEach((to, from) = > {
    const toDepth = to.path.split('/').length
    const fromDepth = from.path.split('/').length
    to.meta.transitionName = toDepth < fromDepth ? 'slide-right' : 'slide-left'
})
Copy the code

This article demo address github.com/kongcodes/v…

Vue3 content