9.路由

9.路由

vue 属于单页面应用,所谓的路由,就是根据浏览器路径不同,用不同的视图组件替换这个页面内容展示

默认路由的配置是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
25
26
27
28
29
30
31
import Vue from 'vue'
import VueRouter from 'vue-router'

// 绝对路径导入,@表示src
import ContainerView from '@/views/example13/ContainerView.vue'
import LoginView from '@/views/example13/LoginView.vue'
import NotFoundView from '@/views/example13/NotFoundView.vue'

Vue.use(VueRouter)

const routes = [
// 建立路径和组件之间的对应关系
{
path:'/',
component: ContainerView
},
{
path:'/login',
component: LoginView
},
{
path:'/404',
component: NotFoundView
}
]

const router = new VueRouter({
routes
})

export default router
  • 在入口main.js中导入编写的路由文件
1
import router from './router/example13' // 导入自定义的路由
  • 修改主视图

    <router-view> 起到占位作用,改变路径后,这个路径对应的视图组件就会占据 <router-view> 的位置,替换掉它之前的内容

1
2
3
4
5
6
7
8
9
10
<template>
<div>
<router-view></router-view>
</div>
</template>

<script>

</script>

动态导入

  • 静态导入是将所有组件的 js 代码打包到一起,如果组件非常多,打包后的 js 文件会很大,影响页面加载速度
  • 动态导入是将组件的 js 代码放入独立的文件,用到时才加载

案例

将上面的静态导入改为动态导入

通过lambda表达式() => import('文件路径')来动态导入

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

// 绝对路径导入,@表示src
// import ContainerView from '@/views/example13/ContainerView.vue'
// import LoginView from '@/views/example13/LoginView.vue'
// import NotFoundView from '@/views/example13/NotFoundView.vue'

Vue.use(VueRouter)

const routes = [
// 建立路径和组件之间的对应关系
{
path:'/',
component: () => import('@/views/example13/ContainerView.vue')
},
{
path:'/login',
component: () => import('@/views/example13/LoginView.vue')
},
{
path:'/404',
component: () => import('@/views/example13/NotFoundView.vue')
}
]

const router = new VueRouter({
routes
})

export default router

嵌套导入

也叫子路由,组件内再要切换内容,就需要用到嵌套路由

通过children属性来定义嵌套路由

案例

定义嵌套路由和重定向

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

Vue.use(VueRouter)

const routes = [
// 建立路径和组件之间的对应关系
{
path:'/',
component: () => import('@/views/example13/ContainerView.vue'),
// 重定向,相当于选择了默认的嵌套路由
redirect: '/c/p1',
// 嵌套路由
children: [
{
path: 'c/p1',
component: () => import('@/views/example13/container/P1View.vue')
},
{
path: 'c/p2',
component: () => import('@/views/example13/container/P2View.vue')
},
{
path: 'c/p3',
component: () => import('@/views/example13/container/P3View.vue')
},

]
},
{
path:'/login',
component: () => import('@/views/example13/LoginView.vue')
},
{
path:'/404',
component: () => import('@/views/example13/NotFoundView.vue')
},
{
// 从定向用法,访问不存在的路径跳转到指定的组件上去
path:'*',
redirect: '/404'
}
]

const router = new VueRouter({
routes
})

export default router

路由跳转

跳转方式:

  • 标签式:通过to属性实现跳转
  • 编程式:自定义方法,通过this.$router.push(url)方式实现跳转

案例

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
<template>
<div class="container">
<el-container>
<el-header>
<!-- 编程式 -->
<el-button icon="el-icon-search" circle size="mini" @click="jump('/c/p1')"></el-button>
<el-button type="primary" icon="el-icon-edit" circle size="mini" @click="jump('/c/p2')"></el-button>
<el-button type="success" icon="el-icon-check" circle size="mini" @click="jump('/c/p3')"></el-button>
</el-header>
<el-container>
<el-aside width="200px">
<!-- 标签式 -->
<router-link to="/c/p1">p1</router-link>
<router-link to="/c/p2">p2</router-link>
<router-link to="/c/p3">p3</router-link>
</el-aside>
<el-main>
<router-view></router-view>
</el-main>
</el-container>
</el-container>
</div>
</template>
<script>
const options = {
methods: {
jump(url) {
// 根据路径进行跳转
this.$router.push(url);
}
}
}
export default options;
</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
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
<template>
<div class="login">
<el-input v-model="username" placeholder="请输入用户名" size="mini"></el-input>
<el-button type="primary" size="mini" @click="login()">登录</el-button>
</div>
</template>
<script>
import axios from '../../utils/myaxios.js'
import {resetRouter} from '@/router/example14'

const options = {
data() {
return {
username: 'admin'
}
},
methods: {
// 将登录用户可以访问的路径添加到路由中
async login() {
resetRouter();
const resp = await axios.get(`/api/menu/${this.username}`)
for (const {id, path, component} of resp.data.data) {
if (component !== null) {
// 在父路由中添加路由
this.$router.addRoute('c', {
path: path,
name: id,
component: () => import(`@/views/example14/container/${component}`)
})
}
}

// 打印路由
console.log(this.$router.getRoutes())
}
}

}

export default options;
</script>





<style scoped>
.login {
height: 100%;
background-color: darkseagreen;
/* background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Ctext x='15' y='10' font-size='14' font-family='system-ui, sans-serif' text-anchor='middle' dominant-baseline='middle'%3E登录%3C/text%3E%3C/svg%3E"); */
}

.el-input--mini {
width: 193px;
margin: 10px 10px 0 10px;
}
</style>

保存路由信息

每次刷新页面,路由信息都会丢失

将路由数据存到localStorage或sessionStorage可以在每次刷新时来恢复路由

router文件中

抽出两个方法:重置路由和添加路由

还有每次运行时查询缓存

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
// 查询sessionStorage中是否有缓存的路由信息
const serverRoutes = sessionStorage.getItem('serverRoutes')
if (serverRoutes) {
const array = JSON.parse(serverRoutes)
addServerRoutes(array)
}


// 重置路由,新建一个路由,把空的matcher赋值给现在的路由
export function resetRouter() {
router.matcher = new VueRouter({routes}).matcher
}

// 添加路由信息
export async function addServerRoutes(array) {
resetRouter();
for (const {id, path, component} of array) {
if (component !== null) {
// 在父路由中添加路由
router.addRoute('c', {
path: path,
name: id,
component: () => import(`@/views/example14/container/${component}`)
})
}
}

}

9.路由
http://xwww12.github.io/2022/10/07/前端/vue/9.路由/
作者
xw
发布于
2022年10月7日
许可协议