vue-router 路由

前端三大框架都有自己的路由 Angular的ngRouter React的ReactRouter Vue的vue-router

vue-router 是官方的路由插件,跟vue深度集成

主要用于配置组件和url映射关系的,俗称跳界面

安装

大家是否还记得,在初始化vueCli时,有一个选项是否选择安装vue-router,如果那时你选择安装,那么ok,vue已经自动帮你配置好了router相关文件

如果没有选择,则需要我们手动安装router

  1. 使用npm下载npm install vue-router --save

  2. 在src目录下 创建文件夹 router 并在下面创建 index.js 文件,配置路由相关信息

  3. 在router下的index.js 中进行配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    import Vue from 'vue' //导入vue
    import VueRouter from "vue-router"; //导入router

    import Home from "../components/Home"; //导入你需要配置router 的组件

    Vue.use(VueRouter)//通过vue.use 安装插件


    const router = new VueRouter({ //配置 router对象
    mode:'history',//加了这句后 地址栏就不会出现#号
    routes:[ //配置路由和组件之间的映射关系
    { // 每个组件的路由配置都以对象的形式存放在 routes数组中
    path: '/home', // 路径,浏览器访问 / 时,则访问Home组件
    name: 'Home', //定义name 属性,值就是上面 import 后面的 名字
    component: Home// 声明 映射的是哪个组件
    },
    {
    path:'/',
    redirect:'/home' //重定向,当地址栏为空时,则自动跳转到 /home
    }
    ]
    })

    export default router //将对象导出
  4. 在 src下的 man.js 引用 router

    1
    2
    3
    4
    5
    6
    7
    import router from './router' //当导入的是一个目录时,会自动寻找该目录下的index文件
    Vue.use(router)
    new Vue({
    el: '#app',
    router, // 将导入的router 挂载到vue实例中
    render:h => h(App)
    })

基本使用

在 src下的 App.vue 中,使用router-link 来创建视图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<template>
<div id="app">
<el-container>
<el-header>
<Header></Header>
</el-header>
<el-main>
<router-view></router-view> // 路由配置的组件将渲染到这里 相当于一个占位符
</el-main>
</el-container>
<Footer></Footer>
</div>
</template>

<script>

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

之后,在组件中使用 router-link 标签 进行视图跳转

其他属性:

replace: 加上replace属性后,点击跳转到该视图后,就不可以使用浏览器的返回键

1
2
3
<router-link to="/" replace>
<a class="nav-link">主页</a>
</router-link>

class属性 router-link-active: 当router-link 被点击以后 会被加上一个 class,值为router-link-active,可以根据这个class值来进行样式操作

1
2
3
4
5
6
<style scoped>
.router-link-active{
color: red;
}
}
</style>

默认是 router-link-active ,当需要指定class名时,可以通过

1
2
3
<router-link to="/" active-class="myclass">
<a class="nav-link">主页</a>
</router-link>

不使用router-link 进行页面视图跳转(通过代码方式):

使用 this.$router.push() / this.$router.replace()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<template>
<button @click="go">主页</button>
</template>
<script>
export default {
name: "header",
data() {
return {};
},
methods:{
go(){
this.$router.push('/home')
//this.$router.replace('/home')
}
}
};
</script>

动态路由

在实际开发中,url地址很可能会跟些其他的东西,比如:
http://localhost:8080/user/username

使用动态路由如下:

在router配置中,在地址后面加上 :参数名 即可接收参数

1
2
3
4
{
path:'/user/:id',
component:user
},
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<template>
<div id="all">

<router-link to="/"><el-button type="primary">返回首页</el-button></router-link>
<router-link :to="/user/userid"><el-button type="primary">查看用户</el-button></router-link> <!-- 使用v-bind,将data中的userid 赋值上去 在地址后面跟上想要传递的参数 -->

</template>
</com> -->
</div>
</template>

<script>
export default {
name: "Header",
data() {
return{
userid:1
}
}
};
</script>
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
<template>
<div id="wapper">
<h1>我的id 是</h1>
</div>
</template>

<script>
export default{
name:'user',
data() {
return{
userid:''
}
},
computed:{
userId(){
return this.$route.params.id
// 使用 $route(不是$router) 对象获取参数,params后的属性就是配置文件中地址栏后自定义的参数名(id)
// $router 是配置文件中new出来的整个对象
// $route 是哪个路由处于活跃状态就会拿到哪个路由对象
}
}
}
</script>

路由的懒加载

当打包构建应用时,js包会变得非常大,影响页面加载

懒加载又叫按需加载,指用到时再加载,只有当路由访问某个组件,才会加载那个组件对应的文件,这样能提高程序运行效率

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import Vue from 'vue' 
import VueRouter from "vue-router";

//import user from "../components/user.vue"
const user = ()=> import('../components/user.vue')
//声明user常量,当需要导入时,则调用这个常量

Vue.use(VueRouter)

const router = new VueRouter({
mode:'history',
routes: [
{
path:'/user',
component:user
},
{
path:'*',//当输入的地址都不匹配上面的路由时 进这里
component:NotFind
},
]});
export default router

路由嵌套/子路由

路由嵌套是指,在一个路由下嵌套多个子路由,如 /home 下还有 /home/user /home/about 两个路由,这两个嵌套路由也会分别渲染两个组件

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
import Vue from 'vue' //导入vue
import VueRouter from "vue-router"; //导入router

import NotFind from "../components/NotFind";
import Home from "../components/Home";
import list from "../components/list";
import user from "../components/user.vue"

Vue.use(VueRouter)

const router = new VueRouter({
mode:'history',
routes: [
{
path:'/Home',
component:Home,
children:[ // 在配置对象中 添加 children 数组,数组里面的对象将作为它的子路由
{
path:'',
redirect:'user' // 当视图跳转到 home 时,重定向到 子路由user
}.
{
path:'user', // 子路由配置,路径不需要加 /
component:user
},
{
path:'list', // 子路由配置,路径不需要加 /
component:list
},
]
},
{
path:'*',//当输入的地址都不匹配上面的路由时 进这里
component:NotFind
},
]});
export default router
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<template>
<div id="wapper">
<router-link to="/home/user">个人中心</router-link>
<router-view></router-view>
<!-- 仍然 使用router-link 进行路由跳转 -->
<!-- 再 为子路由添加 视图 router-view -->

</div>
</template>

<script>
export default {
name: "Home",
data() {
return {
}
},
}
</script>

<style scoped>
</style>

路由参数传递

使用路由传递参数,需要用到 route 的 query 属性取值

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
<template>
<div id="wapper">
<a @click="goUser">用户中心</a>
</div>
</template>

<script>
export default {
name: "Home",
data() {
return {
userId:1
}
},
computed:{
},
methods:{
goUser(){
this.$router.push({
path:'/user',
query:{
id:this.userId
}
})
}
}
}
</script>

<style scoped>
</style>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<template>
<div id="wapper">
<h1>我是{{$route.query.id}}</h1>
</div>
</template>

<script>
export default{
name:'user',
data() {
return{
}
},
}
</script>

<style>
</style>

导航守卫

在路由跳转过程中大致可以分为三个部分, 跳转前 跳转中 跳转后,每一个过程都提供了一个函数类似于生命周期 ,能够让你做一些其他的事

  1. 全局前置守卫 使用了 router.beforeEach

    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
    import Vue from 'vue'
    import VueRouter from 'vue-router'

    import Mainn from '@/components/Main'
    import UserController from '@/components/account/UserController'
    import login from "@/components/account/Login"

    Vue.use(VueRouter)

    const router = new VueRouter({
    mode: 'history',
    routes: [{
    path: '/',
    redirect: '/main'
    },
    {
    path: '/main',
    component: Mainn,
    },
    {
    path: '/user',
    component: UserController,
    },omponent: UploadCenter
    }
    ]
    })

    // 每次route 状态发生变化时,都会调用 这个方法
    router.beforeEach((to, from, next) => {
    //to:到哪里去 form:从哪里来 next:下一步
    //结尾必须调用 next()方法,不然路由不会执行跳转
    var token = sessionStorage.getItem('token')
    if (!token) {
    if (to.path === '/login' || to.path === '/') {
    next()
    } else {
    next({ path: '/login' })
    }
    } else {
    next()
    }
    })

    export default router

  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
30
31
32
33
import Vue from 'vue'
import VueRouter from 'vue-router'

import Mainn from '@/components/Main'
import UserController from '@/components/account/UserController'

Vue.use(VueRouter)

const router = new VueRouter({
mode: 'history',
routes: [{
path: '/',
redirect: '/main'
},
{
path: '/main',
component: Mainn,
props: { //在props属性中定义 name
name: 'fish'
}
},
{
path: '/user',
component: UserController,
beforeEnter: (to, from, next) => {// 路由跳转此界面 调用此方法
console.log(from.matched[0].props.default.name)
next()
}
},

]
})
export default router
  1. 也可以直接在组件中进行处理
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
<template>
<div id="wapper">
<router-link to="user">点我</router-link>
</div>
</template>
<script>

export default {
name:'Main',
data() {
return{
name:'fish'
}
},
beforeRouteLeave(to,from,next) {
let isGo = window.confirm("是否跳转到用户页")
if(isGo){
from.meta.name = this.name
next()
}
else next(false)
}
};

</script>

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
<template>
<div id="wapper">

</div>
</template>

<script>
export default {
name: 'UserController',
data() {
return {
}
},
beforeRouteEnter(to,from,next) {
console.log(`进入了${from.meta.name}的个人界面`)
next()
},
methods: {
}
}
</script>

<style>
</style>

vue-router-keep-alive

keep-alive 是 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
<template>
<div id="app">
<el-container>
<el-header>
<Header></Header>
</el-header>
<el-main>

<!-- 将视图使用 keep-alive 包起来,里面的组件就会缓存下来,不会被销毁,就好比套上了一层保鲜膜 -->
<!-- 使用 exclude属性可以指定排除哪些组件,相反只指定哪些组件使用include -->
<keep-alive exclude="UserController,Setting">
<router-view></router-view>
</keep-alive>


</el-main>
</el-container>
<Footer></Footer>
</div>
</template>

<script>

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

<style>
</style>