Vue Router 是 Vue.js 的官方路由管理器,与 Vue.js 的核心深度集成,可以非常简单地将多个组件映射到多个路由上。
Vue Router 可以简单地理解成页面路由。通过它,我们可以在多个页面间自由跳转,而且通过 Vue.js 的组件化开发,结合 Vue Router 可以构建出非常完整的单页面应用 (SPA)。
Vue Router 相对于传统的后端路由,前端路由技术的特点是不需要后台支持,路由既可以自动切换,也可以手动切换。Vue Router 可以让我们以组件为基础进行构建,然后将组件映射到路由上,来实现页面的跳转和视图的渲染。
安装及使用
在项目中使用 Vue Router 之前,需要先进行安装。
1.使用 npm 安装
```
npm install vue-router
```
2.在 Vue 项目中引入 Vue Router
```
import VueRouter from 'vue-router';
import Vue from 'vue';
Vue.use(VueRouter);
```
3.创建路由实例
```
const router = new VueRouter({
routes: [
{ path: '/home', component: Home },
{ path: '/about', component: About }
]
})
```
4.将路由实例注入到 Vue 实例中
```
new Vue({
el: '#app',
router,
template: '
components: { App }
})
```
上面的代码创建了一个路由实例 `router`,并将其注入到 Vue 实例中,并设置了两个路由:
- `/home` :对应的组件为 `Home`
- `/about` :对应的组件为 `About`
当访问 `/home` 或 `/about` 时,路由会将对应的组件渲染到视图中。
一个完整的 Vue Router 示例代码:
```
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from './components/Home.vue'
import About from './components/About.vue'
Vue.use(VueRouter)
const router = new VueRouter({
routes: [
{ path: '/home', component: Home },
{ path: '/about', component: About }
]
})
new Vue({
el: '#app',
router,
template: `
`
})
```
其中,` Vue Router 配置项说明 Vue Router 的配置项在实际应用中是非常多样化的,可以根据实际需要进行灵活配置。这里对配置项进行说明: - routes:路由配置,用来设置各个路由对应的组件。 ``` const router = new VueRouter({ routes: [ { path: "/home", component: Home }, { path: "/about", component: About } ] }) ``` - mode:路由模式,有 hash 和 history 两种模式,默认为 hash。 ``` const router = new VueRouter({ mode: 'history', routes: [{path: "/", component: Home}] }) ``` - base:路由基础路径。如果整个应用的路由都在子路径下,可以使用这个选项指定基础路径。 ``` const router = new VueRouter({ base: "/test/", routes: [{path: "/", component: Home}] }) ``` - scrollBehavior:滚动行为。通过这个选项可以配置在页面切换时,滚动位置的行为。 ``` const router = new VueRouter({ scrollBehavior (to, from, savedPosition) { return { x: 0, y: 0 } } }) ``` 通过这个选项可以配置一些非常有趣的行为。比如: ``` scrollBehavior (to, from, savedPosition) { if (to.hash) { return { selector: to.hash } } else if (savedPosition) { return savedPosition } else { return { x: 0, y: 0 } } } ``` 当页面存在 hash 时,页面切换时会自动滚动到对应的元素位置;当页面已经发生滚动时,再次返回时会保持原来的滚动位置;其他情况会滚动到顶部。 - linkActiveClass / linkExactActiveClass:激活 class。当页面跳转到对应路由时,可以配置其激活时的 class 样式。 ``` const router = new VueRouter({ routes: [ { path: "/home", component: Home, meta: { title: "首页" } }, { path: "/about", component: About, meta: { title: "关于" } } ], linkActiveClass: "active", linkExactActiveClass: "exact-active" }) ``` 在实际使用中可以根据需要来配置这些选项。 Vue Router API 详解 router.push(location[, onComplete[, onAbort]]) 用来在 JS 代码中动态的切换到新路由,可以传入跳转到的路由的路径,或是一个包含路由信息的对象。 ``` ``` router.replace(location[, onComplete[, onAbort]]) 跟 `router.push()` 方法类似,但是使用 `replace` 跳转时不会留下浏览历史记录。 ``` ``` router.go(n) 向前或向后导航 n 步,类似于 window.history.go(n) 方法。 ``` ``` router.beforeEach((to, from, next) => {}) 这个方法会在每次跳转之前执行,可以用来进行权限认证等操作。 ``` router.beforeEach((to, from, next) => { console.log(`路由跳转:'${from.path}' -> '${to.path}'`); next(); }) ``` router.afterEach((to, from) => {}) 这个方法会在每次路由跳转成功之后执行,可以用来进行根据路由更新页面标题等操作。 ``` router.afterEach((to, from) => { console.log(`路由跳转:'${from.path}' -> '${to.path}'`); document.title = to.meta.title || 'Vue App'; }) ``` 我们可以在这些钩子函数中进行一些额外的操作,比如: 1.对需要登录认证的页面进行权限判断。 2.路由切换时,根据路由信息动态更新页面标题。 3.加载页面时,对页面滚动位置进行处理。等等。 # Vue Router 实例:实现一个简单博客应用 以下是一个简单的博客应用,使用了 Vue.js + Vue Router + Mock.js 搭建而成。主要的功能是展示博客列表,博客分类,以及查看博客详情等。 1.项目结构 ``` ├── App.vue // 根组件 ├── api │ └── index.js // 接口请求模块 ├── assets │ └── logo.png ├── main.js // 入口文件 ├── mock │ └── index.js // 数据模拟模块 ├── router │ └── index.js // 路由管理器 ├── store │ ├── index.js // 状态管理器 │ └── modules │ └── blog.js // 博客状态模块 └── views ├── Blog.vue // 博客主页面 ├── BlogDetail.vue // 博客详情页面 └── NotFound.vue // 404 页面 ``` 2.数据接口定义:`api/index.js` ``` import axios from 'axios'; const API_BASE_URL = 'https://some-domain.com/api'; export const fetchCategories = () => { return axios.get(`${API_BASE_URL}/categories`); } export const fetchBlogs = (params = {}) => { return axios.get(`${API_BASE_URL}/blogs`, {params}); } export const fetchBlogDetail = (blogId) => { return axios.get(`${API_BASE_URL}/blogs/${blogId}`); } ``` 通过 `axios` 库来进行接口调用,并将接口请求封装在不同的方法中,方便调用。 3.数据模拟设置:`mock/index.js` ``` import Mock from 'mockjs'; const Random = Mock.Random; Random.extend({ categories: () => { return [ {id: 1, name: 'Vue.js'}, {id: 2, name: 'React'}, {id: 3, name: 'Angular'}, {id: 4, name: 'jQuery'} ]; }, blogs: () => { let data = []; for (let i = 1; i <= 20; i++) { data.push({ id: i, title: Random.ctitle(15, 20), author: Random.cname(), content: Random.cparagraph(3), created_at: Random.datetime() }); } return data; } }); Mock.mock(/\/categories$/, 'get', 'categories'); Mock.mock(/\/blogs$/, 'get', 'blogs'); Mock.mock(/\/blogs\/\d+$/, 'get', (options) => { let id = options.url.match(/\/blogs\/(\d+)$/)[1]; return { id, title: Random.ctitle(15, 20), author: Random.cname(), content: Random.cparagraph(3), created_at: Random.datetime() }; }); ``` 这里使用了 `Mock.js` 库来模拟接口,实现随机生成博客数据和分类信息。 4.路由管理器:`router/index.js` ``` import VueRouter from 'vue-router'; import Blog from '../views/Blog.vue'; import BlogDetail from '../views/BlogDetail.vue'; import NotFound from '../views/NotFound.vue'; const router = new VueRouter({ mode: 'history', routes: [ { path: '/', redirect: '/blog' }, { path: '/blog', component: Blog }, { path: '/blog/:id', component: BlogDetail }, { path: '*', component: NotFound } ] }); export default router; ``` 这里有三个路由: - `/blog` :博客列表页面 - `/blog/:id` :博客详情页面 - `*` :其他路径均返回 404 页面 5.博客页面组件:`views/Blog.vue` ``` :key="index" :class="{ active: selectedCategory === category.id }" @click="changeCategory(category.id)"> {{ category.name }} :key="blog.id" @click="gotoDetailPage(blog.id)"> {{ blog.author }} · {{ blog.created_at }} ``` 主要包含两个部分: - 左边是通过接口获取到的博客分类信息,点击分类时可以筛选相应的博客列表。 - 右边是博客列表,可以点击列表项进入详情页面。 这里使用了 `mapGetters` 辅助函数,将状态中的数据映射到组件的计算属性中,并分别对博客分类、博客列表、选中的博客分类进行操作。 6.博客详情页面组件:`views/BlogDetail.vue` ``` 作者:{{ currentBlog.author }} 发布时间:{{ currentBlog.created_at }} ``` 展示博客的标题、作者和发布时间,并将博客详情页的内容通过 HTML 绑定的方式展示出来。 7.状态管理器:`store/index.js` 和 `store/modules/blog.js` ``` // store/index.js import Vue from 'vue'; import Vuex from 'vuex'; import blog from './modules/blog'; Vue.use(Vuex); export default new Vuex.Store({ modules: { blog } }); // store/modules/blog.js import * as API from '../../api'; const state = { categories: [], blogs: [], selectedCategory: null, currentBlog: null }; const getters = { categories: state => state.categories, blogs: state => state.blogs, selectedCategory: state => state.selectedCategory, currentBlog: state => state.currentBlog }; const actions = { fetchCategories({commit}) { API.fetchCategories().then(res => { commit('setCategories', res.data); }); }, fetchBlogs({commit, getters}) { let categoryId = getters.selectedCategory; API.fetchBlogs({categoryId}).then(res => { commit('setBlogs', res.data); }); }, fetchBlogDetail({commit}, blogId) { API.fetchBlogDetail(blogId).then(res => { commit('setCurrentBlog', res.data); }); } }; const mutations = { setCategories(state, categories) { state.categories = categories; }, setBlogs(state, blogs) { state.blogs = blogs; }, selectCategory(state, categoryId) { state.selectedCategory = categoryId; }, setCurrentBlog(state, blog) { state.currentBlog = blog; } }; export default { namespaced: true, state, getters, actions, mutations }; ``` 这里使用了 Vuex 管理状态,将所有和博客相关的状态数据和操作都放在了博客模块中。 总结 Vue Router 与 Vue.js 核心深度集成,在实现前端路由时更加便捷快速。通过灵活的配置可以实现非常多样的路由设计。在实际的项目应用中,Vue Router 也是必不可少的一环。 如果你喜欢我们三七知识分享网站的文章,
欢迎您分享或收藏知识分享网站文章
欢迎您到我们的网站逛逛喔!https://www.37seo.cn/
分类
{{ blog.title }}
{{ currentBlog.title }}
一年,辛苦了,忙碌了一年,歇会吧,奋斗了一年,休息会,一天又一天,走过一程又一程,新的一年又开始了,愿自己在新的一年幸福平安!