在构建现代单页应用(SPA)时,路由管理和状态管理是两个核心问题。Vue生态系统提供了Vue Router和Vuex这两个官方库来解决这些问题。本文将详细介绍这两个工具的使用方法和最佳实践,帮助你构建结构清晰、状态可控的Vue应用。
第一部分:Vue Router基础
什么是Vue Router?
Vue Router是Vue.js官方的路由管理器。它与Vue.js核心深度集成,让构建单页应用变得轻而易举。主要功能包括:
- 嵌套路由/视图映射
- 模块化、基于组件的路由配置
- 路由参数、查询、通配符
- 视图过渡效果
- 细粒度的导航控制
- 自动激活CSS类的链接
- HTML5历史模式或hash模式
安装和基本设置
首先,安装Vue Router:
npm install vue-router
然后,在项目中设置路由:
// src/router/index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import HomeView from '../views/HomeView.vue'
import AboutView from '../views/AboutView.vue'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'home',
component: HomeView
},
{
path: '/about',
name: 'about',
component: AboutView
}
]
const router = new VueRouter({
mode: 'history', // 使用HTML5历史模式
base: process.env.BASE_URL,
routes
})
export default router
在主应用文件中使用路由:
// src/main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
new Vue({
router,
render: h => h(App)
}).$mount('#app')
在App.vue中添加路由视图:
<template>
<div id="app">
<nav>
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</nav>
<router-view/>
</div>
</template>
动态路由匹配
通常我们需要将某种模式匹配到所有路由,全都映射到同一个组件。例如,我们可能有一个VideoView组件,对于所有ID不同的视频,都要使用这个组件来渲染:
const routes = [
// 动态路径参数以冒号开头
{ path: '/video/:id', component: VideoView }
]
现在,像/video/1和/video/2这样的URL都会映射到同一个路由。
在组件中可以通过$route.params访问路由参数:
const VideoView = {
template: '<div>Video ID: {{ $route.params.id }}</div>'
}
也可以通过props接收路由参数:
const routes = [
{
path: '/video/:id',
component: VideoView,
props: true // 将路由参数作为props传递给组件
}
]
然后在组件中接收:
export default {
name: 'VideoView',
props: ['id'] // 直接通过props接收路由参数
}
嵌套路由
实际应用中,通常由多层嵌套的组件组合而成。URL的各段对应嵌套的各层组件,例如:
const routes = [
{
path: '/video/:id',
name: 'video',
component: VideoView,
children: [
{
path: 'info1', // 完整路径是/video/:id/info1
name: 'video-info1',
component: VideoInfo1
},
{
path: 'info2', // 完整路径是/video/:id/info2
name: 'video-info2',
component: VideoInfo2
}
]
}
]
在父组件中需要添加<router-view>来显示子路由组件:
<template>
<div class="video-view">
<h1>Video View</h1>
<p>视频id为: {{ id }}</p>
<router-link :to="{ name: 'video-info1', params: { id: id } }">详情1</router-link> |
<router-link :to="{ name: 'video-info2', params: { id: id } }">详情2</router-link>
<router-view /> <!-- 子路由组件将渲染在这里 -->
</div>
</template>
编程式导航
除了使用<router-link>创建导航链接,还可以使用JavaScript代码进行导航:
// 字符串路径
this.$router.push('/home')
// 对象
this.$router.push({ path: '/home' })
// 命名路由
this.$router.push({ name: 'home' })
// 带参数的命名路由
this.$router.push({ name: 'video', params: { id: 123 } })
// 带查询参数
this.$router.push({ path: '/search', query: { q: 'vue' } })
其他导航方法:
this.$router.replace(...):替换当前路由,不会在历史记录中添加新记录this.$router.go(n):前进或后退n步this.$router.back():后退一步this.$router.forward():前进一步