vue-router

vue-router是基于路由和组件的

路由用于设定访问路径, 将路径和组件映射起来.

在vue-router的单页面应用中, 页面的路径的改变就是组件的切换.

安装和使用vue-router

  1. 安装vue-router

    1
    npm install vue-router --save
  2. 在模块化工程中使用

    • 导入路由对象,并且调用Vue.use(VueRouter)
    • 创建路由实例,并且传入路由映射配置
    • 在Vue实例中挂载创建的路由实例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    //配置路由相关的信息
    import Vue from "vue"
    import VueRouter from "vue-router"
    // import Home from "../components/Home.vue"
    // import about from "../components/about.vue"
    // import user from "../components/user.vue"
    //路由懒加载
    const Home = () => import("../components/Home.vue")
    const about = () => import("../components/about.vue")
    const user = () => import("../components/user.vue")
    const HomeNews = () => import("../components/HomeNews.vue")
    const profiles = () => import("../components/profiles.vue")
    const HomeMessage = () => import("../components/HomeMessage.vue")
    //1.通过Vue.use(插件),安装插件
    Vue.use(VueRouter)
    //2.创建VueRouter对象
    const routes =[
    {
    path: '/',
    redirect: '/home'
    },
    {
    path: '/home',
    component: Home,
    meta: {
    title:'首页'
    },

    children:[
    {
    path: '',
    redirect: 'news'
    },
    {
    path: 'news',
    component: HomeNews,
    },
    {
    path: 'message',
    component: HomeMessage,

    }
    ]
    },
    {
    path: '/about',
    component: about,
    meta: {
    title:'关于'
    }
    },
    {
    path: '/user/:id',
    component: user,
    meta: {
    title:'用户'
    }
    },
    {
    path: '/profiles',
    component: profiles,
    meta: {
    title:'档案'
    }
    }
    ]
    const router = new VueRouter({
    //配置路由和组件之间的映射关系
    routes,
    //将默认的hash模式改为history模式
    mode: "history"
    })
    //路由守卫
    //前置钩子
    router.beforeEach((to,from,next) =>{
    //从from跳转到to
    window.document.title = to.matched[0].meta.title
    console.log(to);
    next()
    })
    //3.将router对象传入到Vue实例中
    export default router
    1
    2
    3
    4
    5
    6
    7
    //main.js
    import router from './router'
    new Vue({
    el: '#app',
    router,
    render: h => h(App)
    })
    1
    2
    3
    <router-link to="/home">首页</router-link>
    <router-link to="/about">关于</router-link>
    <router-view></router-view>
  3. 使用vue-router的步骤

    • 创建路由组件

    • 配置路由映射:组件和路由的映射关系

    • 使用路由:通过

      1
      2
      3
      4
      5
      6
      <router-link>
      <router-view>
      <router-link>: 该标签是一个vue-router中已经内置的组件, 它会被渲染成一个<a>标签.
      <router-view>: 该标签会根据当前的路径, 动态渲染出不同的组件.
      网页的其他内容, 比如顶部的标题/导航, 或者底部的一些版权信息等会和<router-view>处于同一个等级.
      在路由切换时, 切换的是<router-view>挂载的组件, 其他内容不会发生改变.

      路由的默认路径

1
2
3
4
5
6
const routers = [{
path: '/',
redirect: '/home'
}]
//path配置的是根路径: /
//redirect是重定向, 也就是我们将根路径重定向到/home的路径下

HTML5的History模式

​ vue-router默认使用URL的hash方式改变路径,hash方式会在路径中加入#。HTML5的History模式不会有这种效果,会更加易读美观。

1
2
3
4
const router = new VueRouter({
routers,
mode: 'history'
})

URL的hash

​ URL的hash也就是锚点(#), 本质上是改变window.location的href属性.我们可以通过直接赋值location.hash来改变href, 但是页面不发生刷新

HTML5的history模式

​ history接口是HTML5新增的, 它有五种模式改变URL而不刷新页面.

1
2
3
4
5
6
history.pushState({},'','/home')
history.replaceState({},'','/home')
history.go(-1)
history.back() 等价于 history.go(-1)
history.forward() 则等价于 history.go(1)
这三个接口等同于浏览器界面的前进后退。

router-link的其他属性

  • tag: tag可以指定之后渲染成什么组件, 比如上面的代码会被渲染成一个

  • 元素, 而不是
  • 1
    <router-link to='/home' tag='li'>
  • replace: replace不会留下history记录, 所以指定replace的情况下, 后退键返回不能返回到上一个页面中

  • active-class: 当对应的路由匹配成功时, 会自动给当前元素设置一个router-link-active的class, 设置active-class可以修改默认的名称.

    在进行高亮显示的导航菜单或者底部tabbar时, 会使用到该类.

    但是通常不会修改类的属性, 会直接使用默认的router-link-active即可.

路由代码跳转

​ 页面的跳转可能需要执行对应的JavaScript代码, 这个时候, 就可以使用第二种跳转方式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<button @click="home">首页</button>
<button @click="about">关于</button>

<script>
export default {
name: 'App',
methods:{
home(){
this.$router.push('home')
},
about(){
this.$router.push('/about')
}
}
</script>

动态路由

​ 在某些情况下,一个页面的path路径可能是不确定的,比如我们进入用户界面时,希望是如下的路径:

  • /user/aaaa或/user/bbbb;
  • 除了有前面的/user之外,后面还跟上了用户的ID
  • 这种path和Component的匹配关系,称之为动态路由(也是路由传递数据的一种方式)。
1
2
3
4
5
6
7
8
{
path: '/user/:id',
component: User
}
<div>
<h2>{{$route.params.id}}</h2>
</div>
<router-link to="/user/123">用户</router-link>

路由的懒加载

  • 路由懒加载的主要作用就是将路由对应的组件打包成一个个的js代码块.
  • 只有在这个路由被访问到的时候, 才加载对应的组件

懒加载前的效果

懒加载后的效果

懒加载的方式

  1. 结合Vue的异步组件和Webpack的代码分析.

    1
    const Home = resolve => { require.ensure(['../components/Home.vue'], () => { resolve(require('../components/Home.vue')) })};
  2. AMD写法

    1
    const About = resolve => require(['../components/About.vue'], resolve);
  3. ES6中, 可以有更加简单的写法来组织Vue异步组件和Webpack的代码分割.

    1
    const Home = () => import('../components/Home.vue')

    嵌套路由

实现嵌套路由有两个步骤:

  1. 创建对应的子组件, 并且在路由映射中配置对应的子路由.
  2. 在组件内部使用标签.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//路由映射中配置对应的子路由.
const routes =[
{
path: '/',
redirect: '/home'
},
{
path: '/home',
component: Home,
meta: {
title:'首页'
},

children:[
{
path: '',
redirect: 'news'
},
{
path: 'news',
component: HomeNews,
},
{
path: 'message',
component: HomeMessage,

}
]
}]
1
2
3
4
5
6
7
//Home.vue
<div>
<h2>我是首页</h2>
<router-link to="/home/news">新闻</router-link>
<router-link to="/home/message">消息</router-link>
<router-view></router-view>
</div>

传递参数

传递参数主要有两种类型: params和query

  • params的类型

    配置路由格式: /router/:id

    传递的方式: 在path后面跟上对应的值

    传递后形成的路径: /router/123, /router/abc

  • query的类型

    配置路由格式: /router, 也就是普通配置

    传递的方式: 对象中使用query的key作为传递方式

    传递后形成的路径: /router?id=123, /router?id=abc

1
2
3
4
5
6
7
8
9
<router-link :to="{
path:'/profiles',
query: {
name: 'cjy',
age: 18
}
}">
档案
</router-link> -->

使用javascript

1
2
3
4
5
6
7
8
9
10
11
methods: {
profiles(){
this.$router.push({
path: '/profiles',
query: {
name: 'cjy',
age: 18
}
})
}
}

获取参数

获取参数通过$route对象获取

在使用了 vue-router 的应用中,路由对象会被注入每个组件中,赋值为 this.$route ,并且当路由切换时,路由对象会被更新。

1
2
3
4
5
<div>
<h2>档案</h2>
<h2>{{$route.params}}</h2>
<h2>{{$route.query.age}}</h2>
</div>

$route和$router的区别

  • $router为VueRouter实例,想要导航到不同URL,则使用$router.push方法
  • $route为当前router跳转对象里面可以获取name、path、query、params等

导航守卫

  • vue-router提供的导航守卫主要用来监听监听路由的进入和离开的.
  • vue-router提供了beforeEach和afterEach的钩子函数, 它们会在路由即将改变前和改变后触发.

利用beforeEach来完成标题的修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
path: '/home',
component: Home,
meta: {
title:'首页'
}


router.beforeEach((to,from,next) =>{
//从from跳转到to
window.document.title = to.matched[0].meta.title
console.log(to);
next()
})

导航钩子的三个参数解析:

to: 即将要进入的目标的路由对象.

from: 当前导航即将要离开的路由对象.

next: 调用该方法后, 才能进入下一个钩子.

afterEach, 不需要主动调用next()函数.

afterEach和beforeEach被称之为全局守卫,还有路由独享的守卫和组件内的守卫。

[]: https://router.vuejs.org/zh/guide/advanced/navigation-guards.html#%E8%B7%AF%E7%94%B1%E7%8B%AC%E4%BA%AB%E7%9A%84%E5%AE%88%E5%8D%AB “路由独享的守卫”


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!