【vue2】路由之 Vue Router

文章目录

  • 一、安装
  • 二、基础使用
    • 1、简单的示例
    • 2、动态路由
      • 2.1 定义动态路径参数
      • 2.2 获取动态路径的参数
      • 2.3 捕获所有路由
    • 3、嵌套路由
    • 4、编程式的导航
      • 4.1 router.push
      • 4.2 router.replace
      • 4.3 router.go(n)
    • 5、命名路由
    • 6、重定向
  • 三、进阶
    • 1、导航守卫
      • 1.1 全局前置守卫
      • 1.2 全局后置钩子
      • 1.3 路由独享的守卫
      • 1.4 组件内的守卫
      • 完整的导航解析流程
    • 2、路由懒加载

一、安装

NPM
注意:vue2中需使用 v.3x 版本

npm install [email protected] --save

vue-router v3.x 文档:文档链接

二、基础使用

1、简单的示例

src/main.js

import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'

// 1. 定义 (路由) 组件。
// 可以从其他文件 import 进来
const Foo = {
  template: '
Foo
'
} const Bar = { template: '
Bar
'
} // 2. 定义路由 // 每个路由应该映射一个组件 const routes = [ { path: '/foo', component: Foo }, { path: '/bar', component: Bar } ] // 3. 创建 router 实例,然后传 `routes` 配置 const router = new VueRouter({ routes }) // 4. 通过 Vue.use() 明确地安装路由功能 Vue.use(VueRouter); // 5. 创建和挂载根实例。 // 通过 router 配置参数注入路由,让整个应用都有路由功能 new Vue({ router, render: h => h(App), }).$mount('#app')

src/App.vue

<template>
  <div id="app">
    <p>
      
      
      
      <router-link to="/foo">Foorouter-link><br />
      <router-link to="/bar">Barrouter-link>
    p>
    
    <router-view>router-view>
  div>
template>

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

2、动态路由

2.1 定义动态路径参数

动态路径参数以冒号开头

const User = {
  template: '
User
'
} const router = new VueRouter({ routes: [ // 动态路径参数 以冒号开头 { path: '/user/:id', component: User } ] })

现在像 /user/123 和 /user/456 都将映射到相同的路由

2.2 获取动态路径的参数

当匹配到一个路由时,参数值会被设置到 this.$route.params,可以在每个组件内使用

const User = {
  template: '
User {{ $route.params.id }}
'
}

可以通过 $route.params 查看所有的参数信息
$route 对象还提供了其它有用的信息

const User = {
  template: '
User {{ $route.params.id }}
'
, created: function () { console.log(this.$route) } }

当路由是 /user/101 时,$route 示例:
【vue2】路由之 Vue Router_第1张图片

2.3 捕获所有路由

可以使用通配符 (*):

{
  // 会匹配所有路径
  path: '*'
}
{
  // 会匹配以 `/user-` 开头的任意路径
  path: '/user-*'
}

3、嵌套路由

要在嵌套的出口中渲染组件,需要在 VueRouter 的参数中使用 children 配置:
src/main.js

import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'

import UserView from './components/UserView.vue'
import FooView from './components/FooView.vue'
import BarView from './components/BarView.vue'

const routes = [
  {
    path: '/user',
    component: UserView,
    children: [
      {
        // 当 /user/foo 匹配成功,
        // FooView 会被渲染在 User 的 
        path: 'foo',
        component: FooView
      },
      {
        // 当 /user/bar 匹配成功,
        // BarView 会被渲染在 User 的 
        path: 'bar',
        component: BarView
      },
    ]
  },
]

const router = new VueRouter({
  routes
})

Vue.use(VueRouter);

new Vue({
  router,
  render: h => h(App),
}).$mount('#app')

顶层 出口,App.vue

<template>
  <div id="app">
    <p>
      <router-link to="/user/foo">Foorouter-link><br />
      <router-link to="/user/bar">Barrouter-link><br />
    p>
    
    <router-view>router-view>
  div>
template>

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

组件同样可以包含自己的嵌套
组件 UserView.vue

<template>
  <div class="user">
    <h2>Userh2>
    <router-view>router-view>
  div>
template>

组件 BarView.vue

<template>
    <div>
        bar
    div>
template>

组件 FooView.vue

<template>
    <div>
        foo
    div>
template>

要注意,以 / 开头的嵌套路径会被当作根路径

4、编程式的导航

4.1 router.push

这个方法会向 history 栈添加一个新的记录
代码实现路由跳转:

router.push(location, onComplete?, onAbort?)
声明式 编程式
router.push(...)

该方法的参数可以是一个字符串路径,或者一个描述地址的对象,示例:

<template>
  <div id="app">
    <div>
      <button @click="routeUser">字符串跳转userbutton>
      <button @click="routeFoo">对象跳转foobutton>
      <button @click="routeBarParams">对象跳转带参数Paramsbutton>
      <button @click="routeBarQuery">对象跳转带参数Querybutton>
    div>
    
    <router-view>router-view>
  div>
template>

<script>
export default {
  name: "App",
  components: {},
  methods: {
    routeUser() {
      // 字符串
      this.$router.push("/user");
    },
    routeFoo() {
      // 对象
      this.$router.push({path: "/foo"});
    },
    routeBarParams() {
      // 命名的路由(带name属性)
      this.$router.push({ name: 'bar', params: { id: '123' }})
    },
    routeBarQuery() {
      // 带查询参数,变成 /bar?id=456
      this.$router.push({ path: '/bar', query: { id: '456' }})
      
      // 注意:如果提供了 path,params 会被忽略
      // 下面的 params 不生效
	  // this.$router.push({ path: '/bar', params: { id }}) // -> /user
    },
  },
};
script>

4.2 router.replace

跟 router.push 很像,唯一的不同就是,它不会向 history 添加新记录

router.replace(location, onComplete?, onAbort?)
声明式 编程式
router.replace(...)

4.3 router.go(n)

这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似 window.history.go(n)。
示例:

// 在浏览器记录中前进一步,等同于 history.forward()
router.go(1)

// 后退一步记录,等同于 history.back()
router.go(-1)

// 前进 3 步记录
router.go(3)

5、命名路由

可以在创建 Router 实例的时候,在 routes 配置中使用 name 给某个路由设置名称:

const router = new VueRouter({
  routes: [
    {
      path: '/user/:userId',
      name: 'user',
      component: User
    }
  ]
})

6、重定向

重定向也是通过 routes 配置来完成,使用 redirect
下面例子是从 /a 重定向到 /b:

const router = new VueRouter({
  routes: [
    { path: '/a', redirect: '/b' }
  ]
})

三、进阶

1、导航守卫

1.1 全局前置守卫

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

const router = new VueRouter({ ... })

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

每个守卫方法接收三个参数:

  • to: Route: 即将要进入的目标 路由对象
  • from: Route: 当前导航正要离开的路由
  • next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。
    • next(): 进行管道中的下一个钩子
    • next(false): 中断当前的导航
    • next(‘/’) 或者 next({ path: ‘/’ }): 跳转到一个不同的地址

确保 next 函数在任何给定的导航守卫中都被严格调用一次。它可以出现多于一次,但是只能在所有的逻辑路径都不重叠的情况下,否则钩子永远都不会被解析或报错

身份时重定向到 /login 的示例:

router.beforeEach((to, from, next) => {
  if (to.name !== 'Login' && !isAuthenticated) {
  	next({ name: 'Login' })
  } else {
	next()
  }
})

1.2 全局后置钩子

也可以注册全局后置钩子,然而和守卫不同的是,这些钩子不会接受 next 函数也不会改变导航本身:

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

1.3 路由独享的守卫

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

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

1.4 组件内的守卫

可以在路由组件内直接定义以下路由导航守卫:
beforeRouteEnter
beforeRouteUpdate
beforeRouteLeave

const Foo = {
  template: `...`,
  beforeRouteEnter(to, from, next) {
    // 在渲染该组件的对应路由被 confirm 前调用
    // 不!能!获取组件实例 `this`
    // 因为当守卫执行前,组件实例还没被创建
  },
  beforeRouteUpdate(to, from, next) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 可以访问组件实例 `this`
  },
  beforeRouteLeave(to, from, next) {
    // 导航离开该组件的对应路由时调用
    // 可以访问组件实例 `this`
  }
}

完整的导航解析流程

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

2、路由懒加载

就是当路由被访问的时候才加载对应的组件
示例:

const Foo = () => import('./Foo.vue')

const router = new VueRouter({
  routes: [{ path: '/foo', component: Foo }]
})

你可能感兴趣的:(Vue,vue.js,前端)