Vue2-router路由
在使用Vue.js构建现代单页面应用程序(SPA)时,路由管理是至关重要的一部分。Vue Router 是 Vue.js 官方的路由管理器,它允许你在应用程序中实现基于组件的页面导航。本文将介绍Vue Router的基本概念和用法,帮助你快速上手Vue.js的路由管理。
什么是路由?
路由在Web开发中指的是确定用户在页面之间导航的机制。在传统的多页面应用中,每次点击链接时浏览器都会向服务器请求一个新的页面。而在单页面应用(SPA)中,所有的页面加载和切换都是在客户端完成的,页面内容通过JavaScript动态更新,而不会重新请求整个页面。
Vue Router 是 Vue.js 官方提供的路由管理器。它和Vue.js核心深度集成,允许你通过简单的配置,将组件映射到路由,然后在应用中进行导航。
安装和基本用法
安装Vue Router:
npm install vue-router
1.配置路由
- 编写路由核心js文件(静态路由配置)
//静态导入是将所有组件的 js 代码打包到一起,如果组件非常多,打包后的 js 文件会很大,影响页面加载速度
import Vue from 'vue'
import VueRouter from 'vue-router'
import View1 from '@/views/1.vue'
import View2 from '@/views/2.vue'
import View3 from '@/views/3.vue'
Vue.use(VueRouter)
const routes = [
{
path: "/",
component: View1
},
{
path: "/login",
component: View2
},
{
path: "/404",
component: View3
}
]
const router = new VueRouter({
routes
})
export default router
- 编写路由核心js文件(动态路由配置)
//动态导入是将组件的 js 代码放入独立的文件,用到时才加载
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
{
path: "/",
component: () => import('@/views/2.vue')
},
{
path: "/login",
component: () => import('@/views/1.vue')
},
{
path: "/404",
component: () => import('@/views/3.vue')
}
]
const router = new VueRouter({
routes
})
export default router
- main.js引入路由
- 在根组件中显示路由
<template>
<div class="all">
<router-view></router-view>
</div>
</template>
其中 <router-view>
起到占位作用,改变路径后,这个路径对应的视图组件就会占据 <router-view>
的位置,替换掉它之前的内容
2.嵌套路由
嵌套路由是指在一个页面路由中包含另一个页面路由的技术。这种技术允许我们在一个父路由内部定义子路由,这些子路由可以在父路由对应的组件中显示,从而形成页面的层级结构。这种层级结构对于复杂的应用程序特别有用,它能够帮助我们模块化地管理和组织页面内容。
- 通过children属性指定要嵌套的路由:
children属性是一个数组,里面存放要映射的对象
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
{
path: "/",
component: () => import('@/views/2.vue'),
redirect: "/c/p1",
children: [
{
path: "c/p1",
component: () => import('@/views/p1.vue')
},
{
path: "c/p2",
component: () => import('@/views/p2.vue')
},
{
path: "c/p3",
component: () => import('@/views/p3.vue')
},
]
},
{
path: "/login",
component: () => import('@/views/1.vue')
},
{
path: "/404",
component: () => import('@/views/3.vue')
},
{
path: "*",
redirect: "/404"
}
]
const router = new VueRouter({
routes
})
export default router
- 通过
<router-view>
标签进行路由的展示
<template>
<div>
<router-view></router-view>
</div>
</template>
3.路由跳转
- 路由重定向
同JavaWeb中的重定向相似,以新路径请求path资源
{
path: "*",
redirect: "/404"
}
<router-link>
标签实现跳转
相当于超链接进行资源的跳转,通过to属性指定要跳转的资源路径
<router-link class="router-link" to="/c/p1">P1</router-link>
<router-link class="router-link" to="/c/p2">P2</router-link>
<router-link class="router-link" to="/c/p3">P3</router-link>
- 路由对象通过push()方法实现跳转
通过获取路由对象,调用push方法将要跳转的资源路径进行传达,实现资源跳转
const options = {
methods: {
jump(url) {
this.$router.push(url);
}
},
};
- 路由结合Element UI菜单导航
通过router和index属性,可以实现菜单导航的跳转
<el-aside width="200px">
<el-menu router background-color="#545c64" text-color="#fff" active-text-color="#ffd04b">
<el-submenu>
<span slot="title">
<i class="el-icon-user-solid"></i>
菜单一
</span>
<el-menu-item index="/c/p1">子项1</el-menu-item>
<el-menu-item index="/c/p2">子项2</el-menu-item>
<el-menu-item index="/c/p3">子项3</el-menu-item>
</el-submenu>
<el-menu-item>
<span slot="title">
<i class="el-icon-picture"></i>
菜单二
</span>
</el-menu-item>
<el-menu-item>
<span slot="title">
<i class="el-icon-s-platform"></i>
菜单三
</span>
</el-menu-item>
</el-menu>
</el-aside>
4.动态路由
动态路由是指根据不同的参数加载不同的路由内容。在Vue Router中,动态路由通常通过在路由路径中使用参数来实现。下面以不同用户身份返回不同的目录访问权限,动态加载路由
- 前端登录环境准备
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
{
path: "/",
name: "c",
component: () => import('@/views/2.vue'),
},
{
path: "/login",
component: () => import('@/views/1.vue')
},
{
path: "/404",
component: () => import('@/views/3.vue')
},
{
path: "*",
redirect: "/404"
}
]
const router = new VueRouter({
routes
})
export default router
<template>
<div class="login">
<h1>登录页面</h1>
<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 "axios";
const options = {
data() {
return {
username:""
}
},
methods: {
async login() {
const response = await axios.get(`/api/login?username=${this.username}`);
console.log(response.data)
}
},
};
export default options;
</script>
<style scoped>
.login {
text-align: center;
background: greenyellow;
width: auto;
height: 100vh;
}
.el-input {
width: 200px;
margin-right: 20px;
}
</style>
- 后端SQL解释
- 添加动态路由
<template>
<div class="login">
<h1>登录页面</h1>
<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 "axios";
const options = {
data() {
return {
username: "",
};
},
methods: {
async login() {
const response = await axios.get(`/api/login?username=${this.username}`);
const array = response.data;
//addRoutes() 参数1:父路由对象名字 参数2:路由对象
for (const { id, path, component } of array) {
if (component !== null) {
this.$router.addRoutes("c", {
path: path,
name: id,
component: () => import(`@/views/${component}`),
});
}
}
},
},
};
export default options;
</script>
<style scoped>
.login {
text-align: center;
background: greenyellow;
width: auto;
height: 100vh;
}
.el-input {
width: 200px;
margin-right: 20px;
}
</style>
- 重置路由
原因:因为每次在动态加载路由的时候只是简单的对路由叠加,这就达不到对路由的动态控制,因此在每次动态添加路由时要重置路由对象,在之前的基础上添加路由,这样才可以达到不同用户权限获得不同的路由权限
//在main.js中添加如下代码
export function resetRouter() {
router.matcher = new VueRouter({ routes }).matcher
}
//重建新的路由对象代替旧的路由对象,matcher属性是获得路由的内容
- 页面刷新与路由
页面刷新后,会导致动态添加的路由失效,解决方法是将路由数据存入 sessionStorage
methods: {
async login() {
resetRouter(); // 重置路由
const resp = await axios.get(`/api/menu/${this.username}`)
const array = resp.data;
// localStorage 即使浏览器关闭,存储的数据仍在
// sessionStorage 以标签页为单位,关闭标签页时,数据被清除
sessionStorage.setItem('serverRoutes', JSON.stringify(array))
addServerRoutes(array); // 动态添加路由
this.$router.push('/');
}
}
页面刷新,重新创建路由对象时,从 sessionStorage 里恢复路由数据
const router = new VueRouter({
routes
})
// 从 sessionStorage 中恢复路由数据
const serverRoutes = sessionStorage.getItem('serverRoutes');
if(serverRoutes) {
const array = JSON.parse(serverRoutes);
addServerRoutes(array) // 动态添加路由
}