喜迎
春节

Vue-router


前言:vue-router是什么?为什么我们不像原来一样直接用 a 标签编写链接?如何使用?常见路由操作有哪些?

Vue Router是什么

Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。包含的功能有:

  • 嵌套的路由/视图表
  • 模块化的、基于组件的路由配置
  • 路由参数、查询、通配符
  • 基于 Vue.js 过渡系统的视图过渡效果
  • 细粒度的导航控制
  • 带有自动激活的 CSS class 的链接
  • HTML5 历史模式或 hash 模式,在 IE9 中自动降级
  • 自定义的滚动条行为
注意:route指的是当前页面的所有路由信息,router是路由的方法。
<router-link to="xxx" tag=" ">
//  将原本用a标签跳转的功能用router-link实现
//  to是指要跳转到的目录,tag是这个点击跳转标签的样式,可以是li的样式等等

router-link-exact-active: 路由完全匹配,当前选中
router-link-active: 路由不完全匹配
to: 表示目标路由的链接。当被点击后,内部会立刻把 to 的值传到 router.push(),所以这个值可以是一个字符串或者是描述目标位置的对象。

<!-- 字符串 -->
<router-link to="home">Home</router-link>
<!-- 渲染结果 -->
<a href="home">Home</a>

<!-- 使用 v-bind 的 JS 表达式 -->
<router-link v-bind:to="'home'">Home</router-link>

<!-- 不写 v-bind 也可以,就像绑定别的属性一样 -->
<router-link :to="'home'">Home</router-link>

<!-- 同上 -->
<router-link :to="{ path: 'home' }">Home</router-link>

<!-- 命名的路由 -->
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>

<!-- 带查询参数,下面的结果为 /register?plan=private -->
<router-link :to="{ path: 'register', query: { plan: 'private' }}">Register</router-link>

编程式导航

除了使用 router-link 标签创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现。
this.$router.push():括号里面参数和to的方法一致

// 字符串
router.push('home')

// 对象
router.push({ path: 'home' })

// 命名的路由
router.push({ name: 'user', params: { userId: '123' }})

// 带查询参数,变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})
  • 注意:如果提供了 path,params 会被忽略,上述例子中的 query 并不属于这种情况。取而代之的是下面例子的做法,你需要提供路由的 name 或手写完整的带有参数的 path:
const userId = '123'
router.push({ name: 'user', params: { userId }}) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
// 这里的 params 不生效
router.push({ path: '/user', params: { userId }}) // -> /user

动态路由和嵌套路由

动态路由:一个“路径参数”使用冒号 : 标记。当匹配到一个路由时,参数值会被设置到this.$route.params

注意:子路由path不写斜线

import Home from '../views/Home'
import Products from '../views/Products'
import Category from '../views/Category'
export default [
  {
    path: '/home',
    name: 'home',
    component: Home
  }, {
    path: '/Products',
    name: 'products',
    component: Products,
    children: [{
      path: ':cateName',//子路由path不写斜线
      name: 'category',
      component: Category
    }]
  }
]

router-view

子路由(children)的router-view要在父组件里面去配置

命名视图

有时候想同时 (同级) 展示多个视图,而不是嵌套展示,例如创建一个布局,有 sidebar (侧导航) 和 main (主内容) 两个视图。你可以在界面中拥有多个单独命名的视图,而不是只有一个单独的出口。如果 router-view 没有设置名字,那么默认为 default

<template>
  <div id="app">
    <h2>头部</h2>
    <div class="main"><router-view></router-view></div>
  <router-view name="x-footer"></router-view>
  </div>
</template>

export default [
  {
    path: '/home',
    name: 'home',
    components: {//这里一定要写components,default指的是没有没有命名的那个组件(在这里是app.vue)
      default: Home,
      'x-footer': Footer
    }
  }

捕获所有路由或 404 Not found 路由

常规参数只会匹配被 / 分隔的 URL 片段中的字符。如果想匹配任意路径,我们可以使用通配符 (*):

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

重定向 redirect和别名alias

注意:含有通配符的路由应该放在最后

export default [
  {//从"/"重定向到"/home",这样根路径就变成了home
    path: '/',
    redirect: '/home'
  }
]

导航守卫(常用来做权限验证)

vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航

全局前置守卫-beforeEach

全局导航守卫可以在main.js里做,因为需要在router的实例上做,用来做全局的权限验证

  const router = new VueRouter({ ... })
  router.beforeEach((to, from, next) => {
    next()
  })

to: 要到哪个组件去,
from: 从哪个组件来的
next: 必须要调用next( )这个方法否则路由无法跳转访问

  • 在路由里除了本身参数,要加入扩展参数时使用meta

组件内的守卫

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

beforeRouteUpdate: 路由更新之前,这里可以发送ajax请求。在使用beforeRouteUpdate时一般会先使用beforeRouteEnter。
beforeRouteEnter中不能获取this,可以在next里传一个回调函数,该回调函数的第一个形参VM就是this,且beforeRouteEnter只会在第一次进来时执行一次。

在之前没有beforeRouteUpdate,使用watch来替代 ,watch可以watch this.上的所有东西

路由懒加载

把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,利用import返回promise来异步加载

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

把组件按组分块,下面的注释意思是:将这三个组件的代码打包到一个js文件里。

const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue')
const Bar = () => import(/* webpackChunkName: "group-foo" */ './Bar.vue')
const Baz = () => import(/* webpackChunkName: "group-foo" */ './Baz.vue')

native 在加不上事件的时候使用,往当前组件的的根dom元素上绑定一个事件


文章作者: NekoDeng
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 NekoDeng !
评 论
 上一篇
关于在Vue项目初始化echarts时报错TypeError:Cannot read property ‘init‘ of undefined的解决办法
关于在Vue项目初始化echarts时报错TypeError:Cannot read property ‘init‘ of undefined的解决办法
前言:在Vue项目中遇到的一个问题,初始化echarts时报错TypeError:Cannot read property ‘init‘ of undefined的解决办法 导入echarts 在Vue项目中的main.js文件中导入如下
2020-09-30
下一篇 
React-生命周期详解
React-生命周期详解
前言: 只有class组件才有生命周期,function式的组件见没有生命周期(生命周期其实就是里面的一些回调函数) 生命周期阶段 挂载阶段 constructor(props)(在这里初始化state,这个只会执行一次),如果不初始
2020-09-29
  目录