vue3(八)Vue Router

265 阅读2分钟

Vue Router api

常用方法

import { createRouter, createWebHistory, createWebHashHistory } from 'vue-router'

  • createRouter 定义一些路由
  • createWebHistory HTML5 模式 路由
  • createWebHashHistory Hash 模式 路由

Router 简单使用 声明式

// 1. 定义路由组件.
// 也可以从其他文件导入
const Home = { template: '<div>Home</div>' }
const About = { 
    template: '<div class="About">
                <h2>User {{ $route.params.username }}</h2>
                <router-view></router-view>
                </div>' 
}
const About2 = { template: '<div>About2</div>' }
const About3 = { template: '<div>About3</div>' }

// 2. 定义一些路由
// 每个路由都需要映射到一个组件。
// 我们后面再讨论嵌套路由。
const routes = [
  { path: '/', component: Home },
  { 
      path: '/about/:id', 
      component: About,
      children: [ 
          { 
          // 当 /about/:id/About2 匹配成功 
          // UserProfile 将被渲染到 User 的 <router-view> 内部 
          path: 'About2', 
          component: About2, 
          }, { 
          // 当 /about/:id/About3 匹配成功 
          // UserPosts 将被渲染到 User 的 <router-view> 内部 
          path: 'About3', 
          component: About3, 
          }, 
       ],
  },
]

// 3. 创建路由实例并传递 `routes` 配置
// 你可以在这里输入更多的配置,但我们在这里
// 暂时保持简单
const router = VueRouter.createRouter({
  // 4. 内部提供了 history 模式的实现。为了简单起见,我们在这里使用 hash 模式。
  history: VueRouter.createWebHashHistory(),
  routes, // `routes: routes` 的缩写
})

// 5. 创建并挂载根实例
const app = Vue.createApp({})
//确保 _use_ 路由实例使
//整个应用支持路由。
app.use(router)

app.mount('#app')

// 现在,应用已经可以启动了!

通过调用 app.use(router),我们会触发第一次导航且可以在任意组件中以 this.$router 的形式访问它,并且以 this.$route 的形式访问当前路由:

Router 编程式

// 字符串路径
router.push('/users/eduardo')

// 带有路径的对象
router.push({ path: '/users/eduardo' })

// 命名的路由,并加上参数,让路由建立 url
router.push({ name: 'user', params: { username: 'eduardo' } })

// 带查询参数,结果是 /register?plan=private
router.push({ path: '/register', query: { plan: 'private' } })

// 带 hash,结果是 /about#team
router.push({ path: '/about', hash: '#team' })

命名视图

代码

<template>
    <h1>Named Views</h1>
    <ul>
        <li>
            <router-link to="/">First page</router-link>
        </li>
        <li>
            <router-link to="/other">Second page</router-link>
        </li>
    </ul>
    <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>
</template>
import { createRouter, createWebHistory } from 'vue-router'

import First from './views/First.vue'

import Second from './views/Second.vue'

import Third from './views/Third.vue'

  


export const router = createRouter({
    history: createWebHistory(),
    routes: [
        {
            path: '/',
            // a single route can define multiple named components
            // which will be rendered into <router-view>s with corresponding names.
            components: {
                default: First,
                a: Second,
                b: Third,
            },
        },
        {
            path: '/other',
            components: {
                default: Third,
                a: Second,
                b: First,
             },
        },
    ],
})

导航守卫

vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。这里有很多方式植入路由导航中:全局的,单个路由独享的,或者组件级的

全局前置守卫

你可以使用 router.beforeEach 注册一个全局前置守卫:

const router = createRouter({ ... })

router.beforeEach((to, from) => {
  // ...
  // 返回 false 以取消导航
  return false
})

可以返回的值如下:

  • false: 取消当前的导航。如果浏览器的 URL 改变了(可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
  • 一个路由地址: 通过一个路由地址跳转到一个不同的地址,就像你调用 router.push() 一样,你可以设置诸如 replace: true 或 name: 'home' 之类的配置。当前的导航被中断,然后进行一个新的导航,就和 from 一样。

路由独享的守卫

你可以直接在路由配置上定义 beforeEnter 守卫:

const routes = [
  {
    path: '/users/:id',
    component: UserDetails,
    beforeEnter: (to, from) => {
      // reject the navigation
      return false
    },
  },
]

完整的导航解析流程#

  1. 导航被触发。
  2. 在失活的组件里调用 beforeRouteLeave 守卫。
  3. 调用全局的 beforeEach 守卫。
  4. 在重用的组件里调用 beforeRouteUpdate 守卫(2.2+)。
  5. 在路由配置里调用 beforeEnter
  6. 解析异步路由组件。
  7. 在被激活的组件里调用 beforeRouteEnter
  8. 调用全局的 beforeResolve 守卫(2.5+)。
  9. 导航被确认。
  10. 调用全局的 afterEach 钩子。
  11. 触发 DOM 更新。
  12. 调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。