Vue 路由模式主要有两种:哈希模式(Hash Mode)和历史模式(History Mode)。
哈希模式(Hash Mode):
在哈希模式下,URL 中的路径会以 #
符号开头,在这种模式下,实际的路径是在 #
符号之后,而不会触发浏览器向服务器发送请求。这样可以避免浏览器刷新页面时发送请求,适用于单页应用。
在 Vue 中,默认就是哈希模式,你不需要额外的配置,只需创建一个路由实例即可:
import Vue from 'vue';
import VueRouter from 'vue-router';
Vue.use(VueRouter);
const router = new VueRouter({
mode: 'hash', // 默认就是 'hash' 模式
routes: [
// 路由配置
]
});
历史模式(History Mode):
在历史模式下,URL 中的路径更具传统的形式,不再带有 #
符号,在这种模式下,需要服务器的支持,以确保在直接访问或刷新页面时能够正确处理路由。
若要使用历史模式,需要配置 mode
为 'history'
,并在服务器端进行相关设置。以下是一个基本的配置示例:
import Vue from 'vue';
import VueRouter from 'vue-router';
Vue.use(VueRouter);
const router = new VueRouter({
mode: 'history', // 使用 'history' 模式
routes: [
// 路由配置
]
});
在 Element UI,可以在项目中使用 Element UI 的导航组件如 <el-menu>
和 <el-menu-item>
,并根据不同的路由模式进行相应的配置。例如,可以在菜单项中使用 <router-link>
组件来实现导航:
<template>
<el-menu :default-active="activeMenu" mode="horizontal" @select="handleMenuSelect">
<el-menu-item index="/home">
<router-link to="/home">Home</router-link>
</el-menu-item>
<el-menu-item index="/about">
<router-link to="/about">About</router-link>
</el-menu-item>
</el-menu>
</template>
<script>
export default {
data() {
return {
activeMenu: '' // 用于记录当前激活的菜单项
};
},
methods: {
handleMenuSelect(index) {
this.activeMenu = index;
}
}
}
</script>
<router-link>
组件被用于创建带有正确路由的链接,这样用户点击菜单项时就会触发路由切换。在实际项目中,可以根据具体需求配置路由模式,并使用 Element UI 或其他 UI 库提供的组件来构建用户界面。
$router
和 $route
是与路由相关的两个对象,它们分别代表了路由器和当前路由的信息。主要区别如下:
$router:
$router
是 Vue 路由器的实例,提供了一系列导航方法,如 push
、replace
和 go
,用于在应用程序中进行路由导航。$router
允许你通过编程的方式进行路由跳转,而不依赖于声明式的组件内部导航(例如 <router-link>
)。this.$router
访问。$route:
$route
是当前活动的路由对象,包含了当前路由的信息,如路径、参数、查询参数、哈希等。$route
可以用于访问当前路由的各种信息,例如在组件内获取当前路径 this.$route.path
,或者获取查询参数 this.$route.query
。$route
是一个响应式对象,当路由发生变化时,相关组件会自动更新。<template>
<div>
<p>当前: {{ $route.path }}</p>
<p>查询参数: {{ $route.query }}</p>
<el-button @click="goToAbout">Go to About</el-button>
</div>
</template>
<script>
export default {
methods: {
goToAbout() {
// 使用 $router 进行编程式导航
this.$router.push('/about');
}
}
}
</script>
$route.path
用于获取当前路由的路径,$route.query
用于获取查询参数。$router.push('/about')
使用 $router
对象进行编程式导航,将用户导航到 “/about” 路由。
在 Vue 中,常见的路由跳转方式包括:
声明式导航(Declarative Routing):
使用 <router-link>
组件进行声明式的导航,该组件会自动渲染为合适的 <a>
标签,通过 to
属性指定目标路由。
<template>
<router-link to="/home">Go to Home</router-link>
</template>
编程式导航(Programmatic Routing):
使用 $router
对象进行编程式导航,通常在组件内部的方法中执行。在这里,可以使用 this.$router.push()
来导航到目标路由。
<script>
export default {
methods: {
goToHome() {
this.$router.push('/home');
}
}
}
</script>
<template>
<div>
<!-- 声明式导航 -->
<router-link to="/home">
<el-button type="primary">Go to Home</el-button>
</router-link>
<!-- 编程式导航 -->
<el-button type="success" @click="goToAbout">Go to About</el-button>
</div>
</template>
<script>
export default {
methods: {
goToAbout() {
// 使用编程式导航
this.$router.push('/about');
}
}
}
</script>
我们使用了 Element UI 的按钮组件来触发路由的跳转。<router-link>
用于声明式导航,而 this.$router.push()
用于编程式导航。
Vue 路由守卫用于在导航过程中对路由进行控制,可以在路由跳转前、跳转后、组件渲染前等不同阶段执行一些代码逻辑。Vue 提供了全局守卫、路由独享守卫、组件内守卫等多种类型的守卫。
全局前置守卫 (beforeEach
):
在路由跳转前执行,常用于进行权限验证或全局设置。
import router from './router';
router.beforeEach((to, from, next) => {
// 在此处进行权限验证或其他逻辑
if (to.meta.requiresAuth && !isAuthenticated) {
// 未登录,重定向到登录页
next('/login');
} else {
// 继续路由跳转
next();
}
});
全局解析守卫 (beforeResolve
):
在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后调用。
router.beforeResolve((to, from, next) => {
// 在此处执行解析逻辑
next();
});
全局后置守卫 (afterEach
):
在路由跳转后执行,常用于记录日志或进行页面埋点等操作。
router.afterEach((to, from) => {
// 在此处执行后置逻辑
});
路由独享守卫 (beforeEnter
):
在单个路由配置中定义,对特定路由生效。
const router = new VueRouter({
routes: [
{
path: '/admin',
component: Admin,
beforeEnter: (to, from, next) => {
// 在此处执行路由独享守卫逻辑
if (isAdmin) {
next();
} else {
next('/login');
}
}
}
]
});
组件内守卫:
在组件内部定义 beforeRouteEnter
、beforeRouteUpdate
和 beforeRouteLeave
方法。
export default {
beforeRouteEnter(to, from, next) {
// 在组件渲染前执行
next(vm => {
// 可以访问实例 `vm`
});
},
beforeRouteUpdate(to, from, next) {
// 在组件复用时调用
// 可以访问组件实例 `this`
next();
},
beforeRouteLeave(to, from, next) {
// 在组件离开时调用
// 可以访问组件实例 `this`
next();
}
};
router.beforeEach((to, from, next) => {
if (to.meta.requiresAuth && !isAuthenticated) {
// 使用 Element UI 的消息框提示用户
this.$message.error('请先登录');
// 未登录,重定向到登录页
next('/login');
} else {
// 继续路由跳转
next();
}
});
路由参数:
通过在路由路径中添加参数,可以使用$route.params
来访问这些参数。
// 路由配置
const routes = [
{ path: '/user/:id', component: User }
];
// 组件中获取参数
this.$route.params.id
Element UI:
<!-- 使用el-link传递参数 -->
<el-link :to="{ path: '/user/' + userId }">Go to User</el-link>
查询参数:
使用查询参数,可以通过$route.query
来获取。
// 路由配置
const routes = [
{ path: '/user', component: User }
];
// 组件中获取参数
this.$route.query.id
Element UI:
<!-- 使用el-link传递查询参数 -->
<el-link :to="{ path: '/user', query: { id: userId }}">Go to User</el-link>
命名路由:
使用命名路由,可以在$route.params
中直接获取。
// 路由配置
const routes = [
{ path: '/user/:id', name: 'user', component: User }
];
// 组件中获取参数
this.$route.params.id
Element UI:
<!-- 使用el-link传递参数 -->
<el-link :to="{ name: 'user', params: { id: userId }}">Go to User</el-link>
props传参:
可以通过在路由配置中使用props来直接将参数传递给组件。
// 路由配置
const routes = [
{ path: '/user/:id', component: User, props: true }
];
// 组件中通过props接收参数
props: ['id']
Element UI:
<!-- 使用el-link传递参数 -->
<el-link :to="{ path: '/user/' + userId, props: true }">Go to User</el-link>
当在Vue应用中刷新页面时,页面的状态和参数通常会丢失,这是因为刷新页面会重新加载整个应用,导致 Vue 实例重新创建。
使用路由参数:
将页面状态信息放在路由的路径中,以便在刷新页面时能够重新获取。这样,即使刷新页面,路由参数仍然会被保留。
// 路由配置
const routes = [
{ path: '/user/:id', component: User }
];
// 在组件中获取参数
this.$route.params.id
Element UI 的 el-link
<!-- 使用el-link传递参数 -->
<el-link :to="{ path: '/user/' + userId }">Go to User</el-link>
使用localStorage或sessionStorage:
将页面状态信息存储在 localStorage
或 sessionStorage
中,以便在页面刷新时检索。
// 存储数据
localStorage.setItem('userId', userId);
// 获取数据
const userId = localStorage.getItem('userId');
在 Vue 组件的生命周期钩子中使用:
mounted() {
const userId = localStorage.getItem('userId');
// 使用 userId 进行其他操作
}
使用 localStorage
或 sessionStorage
存储的数据在页面关闭后仍然存在,需要手动清除或者通过其他方式进行管理。
使用Vuex:
如果应用状态较为复杂,可以使用 Vuex 来管理全局状态。即使页面刷新,Vuex 中的状态仍然可以被保留。
// 在 Vuex store 中定义状态
state: {
userId: null
}
// 在组件中获取状态
this.$store.state.userId
在页面刷新后,你需要通过触发某个事件或在应用初始化时从其他地方恢复这些状态。