访问某个地址,显示 Vue 应用里的某个特定的组件(页面),这个就是 Vue Router 提供的路由功能。这里说的组件,我们也可以理解成是一个页面,比如用户登录页面,内容列表页面,显示单个内容的页面,这些页面组件跟一般的组件没什么区别,对于 Vue 来说,它们都是组件(Component)。
Vue Router
安装 Vue Router
打开项目根目录下的 package.json ,在项目的依赖里添加一个 vue-router。
"dependencies": { // ... "vue-router": "^4.0.0-0" },
在终端,Vue 项目所在目录的下面,执行 yarn
或者 npm install
,准备好项目依赖的东西,包管理工具会把新添加的 vue-router 下载安装到我们的项目里。
路由器
给 Vue 项目装好 vue-router 以后,可以先去创建一个路由器,然后告诉应用使用一下这个路由器就可以了。后面我们会再去定义一些路由,再把这些路由放到这个路由器里。
1:创建路由器
src/app/app.router.js<新建>
import { createRouter, createWebHistory } from 'vue-router'; /** * 创建路由器 */ const router = createRouter({ history: createWebHistory(), routes: [], }); /** * 默认导出 */ export default router;
在 src/app 的下面,新建一个叫 app.router.js 的文件,在里面可以创建并导出一个路由器。创建路由器用的就是 vue-router 里的 createRouter 这个函数。提供一个配置对象参数,里面可以设置一下路由的 history 模式。createWebHistory 这个函数可以创建一个 HTML5 的 history,一般单页面应用(SPA)都会使用这种 history,我们正在开发的这个 Vue 应用就是一个单页面应用。
在创建这个路由器的时候可以把路由器里的路由放在 routes 属性里面,暂时先使用一个空白的数组,在后面我们再定义一些路由,再把这些路由交给这个属性。
2:使用路由器
有了路由器以后还得再告诉 Vue 应用一声,让它使用这个路由器。
main.js<修改>
//... import appRouter from './app/app.router'; //... /** * 应用路由 */ app.use(appRouter); // ...
打开应用的入口文件 main.js,在创建了 app 的下面,可以找个地方用一下 app 上面的 use,使用在上面导入的 appRouter,这个东西就是之前我们在 app.router 里面,使用 createRouter 创建的一个路由器。现在应用就有路由器了。
路由
定义一条路由其实就是设置一下访问某个地址的时候对应要显示的是哪个 Vue 组件。
1:定义路由组件
src/app/components/app-home.vue
<template> <div>欢迎访问宁皓网!</div> </template>
先创建一个组件,等会儿定义路由的时候会用到这个组件,这个组件可以作为应用的首页,也就是访问首页的时候会显示这个组件。
2:定义路由
src/app/app.routes.js<新建>
import AppHome from './components/app-home.vue'; /** * 定义路由 */ const routes = [ { name: 'home', path: '/', component: AppHome, }, ]; /** * 默认导出 */ export default routes;
创建一个新的文件,放在 src/app 的下面,文件的名字叫 app.routes.js ,注意这里用的是 routes 不是 router。应用整体相关的路由都可以放在这个路由文件里。
在 app.routes 里面,我们声明了一个叫 routes 的东西,它的值是一个数组,里面可以放一组路由对象。最后在这个文件里默认导出了 routes。
每一条路由就是一个对象,里面有一些特定的属性,比如 name 可以设置路由的名字,path 设置的是路由的地址,component 设置的是对应的组件。
上面这条路由它的名字叫 home,地址是 / ,表示应用的根,也就是应用的首页,component 设置成了 AppHome,也就是当访问 / 这个地址的时候,页面上就会显示 AppHome 这个组件。
3:把路由交给路由器
src/app/app.router.js<修改>
import { createRouter, createWebHistory } from 'vue-router'; import appRoutes from './app.routes'; /** * 创建路由器 */ const router = createRouter({ history: createWebHistory(), routes: [...appRoutes], }); /** * 默认导出 */ export default router;
定义的路由要放在路由器里,打开之前创建的 app.router 路由器,先在这个文件里导入 appRoutes,然后把它里面的东西交给路由器的 routes ,这里用了一个展开操作符(...)。
4:路由器视图
src/app.vue<修改>
<template> <h1>{{ appName }}</h1> <router-view></router-view> </template> <script> export default { data() { return { appName: '宁皓网', }; }, }; </script>
App 这个组件是应用的 Root Component(根组件 / 主组件),因为在应用的入口文件那里创建 Vue 应用的时候,提供了这个组件,所以它就是应用的主组件。在这个组件的模板里,要添加一组 router-view 组件,路由对应的组件会在这里显示。比如在访问 / 这个地址的时候,在这里就会显示 AppHome 这个组件的内容。
5:预览
访问应用的首页,你会看到在页面上会显示 AppHome 组件里的东西。
内容列表
我希望在访问 /posts 这个地址的时候,可以显示一组内容列表,也就是显示 PostList 这个组件。
1:调整组件结构
现在内容列表与列表项目组件是在 src/post/components 目录的下面,我们把这个 components 目录可以放在 src/post/index 目录的下面,跟内容列表相关的东西,都可以放在 src/post/index 这个目录里。
2:新建 PostIndex 组件
src/post/index/post-index.vue<新建>
<template> <PostList /> </template> <script> import PostList from './components/post-list'; export default { components: { PostList, }, }; </script>
新建一个组件,放在 src/post/index 的下面,名字是 post-index.vue。在这个组件的模板里用一下 PostList 组件。
3:新建内容相关路由
src/post/post.routes.js<新建>
import PostIndex from './index/post-index.vue'; /** * 定义路由 */ const routes = [ { name: 'postIndex', path: '/posts', component: PostIndex, }, ]; /** * 默认导出 */ export default routes;
跟内容相关的路由都可以放在这个 post.routes 文件里。先添加一个内容列表路由,名字叫 postIndex,地址是 /posts,对应的组件是 PostIndex。这样在访问 /posts 这个地址的时候,显示的就是 PostIndex 组件,在这个组件的模板里用了 PostList 组件,所以也就会显示一组内容列表。
4:把路由交给路由器
src/app/app.router.js<修改>
//... import postRoutes from '@/post/post.routes'; /** * 创建路由器 */ const router = createRouter({ history: createWebHistory(), routes: [...appRoutes, ...postRoutes], }); // ...
导入 postRoutes,把它里面的东西放到路由器的 routes 属性里。
5:预览
现在访问 /posts 这个地址的时候,会在页面上显示一组内容列表。
内容页面
下面我们可以去给内容页面定义一条路由,访问某个具体地址的时候可以显示某个特定的内容。这个路由的地址里要支持使用地址参数,一般这个参数就是内容的 id,在路由对应的组件那里,可以从路由里面获取到当前路由地址里的内容 id 参数的值,组件(页面)可以根据这个 id 的值去请求某个特定的内容数据。
1:创建内容页面(组件)
src/post/show/post-show.vue<新建>
<template> <div class="post-show"> <h3>{{ post.title }}</h3> - <small v-if="post.user">{{ post.user.name }}</small> </div> </template> <script> import { apiHttpClient } from '@/app/app.service'; export default { props: { postId: String, }, data() { return { post: {}, }; }, created() { this.getPostById(this.postId); }, methods: { async getPostById(postId) { try { const response = await apiHttpClient.get(`/posts/${postId}`); this.post = response.data; } catch (error) { console.log(error); } }, }, }; </script>
新建一个组件,名字是 post-show.vue,放在 src/post/show 目录的下面。这个组件支持一个 postId 属性,这个属性的值应该是某个内容的 id 。属性具体的值可以从路由那里得到。
在 data 方法里,组件返回了一个叫 post 的数据,这个数据的值就是要在组件里显示的某个内容数据。内容数据要请求服务端应用的内容接口获取到,这件事可以定义成一个方法,放在 methods 里面,方法的名字叫 getPostById,方法接收一个 postId 参数,参数的值应该是某个内容的 id。
在组件里添加了一个 created 生命周期,组件被创建以后会调用这个方法,在它里面我们执行了一下在组件里定义的 getPostById 这个方法,把组件的 postId 属性的值交给了这个方法,这个方法会从服务端那里得到某个特定的内容数据。在组件的模板里绑定输出了内容的标题,还有内容作者的名字。
2:定义路由
src/post/post.routes.js<修改>
//... import PostShow from './show/post-show.vue'; /** * 定义路由 */ const routes = [ //... { name: 'postShow', path: '/posts/:postId', component: PostShow, props: true, }, ]; //...
在内容相关的路由里先导入 PostShow 组件,然后定义一条新的路由,路由的名字叫 postShow,路由的地址是 /posts/:postId,这个地址里的 :postId 是一个地址参数,地址里带冒号前缀的都算是地址参数。/posts/1,/posts/16 这些都匹配这个路由。如果访问的是 /posts/16 ,那在路由里的 postId 这个地址参数的值就相当于是被设置成了 16 。
注意这条路由里我们把 props 设置成了 true,意思是把路由地址参数用属性的方式传递给路由组件。这条路由里有个 postId 参数,那在这个路由对应的组件那里就可以声明一个叫 postId 的属性。比如在访问 /posts/16 的时候,路由就会把路由组件里的 postId 这个参数的值设置成 16 。
3:路由链接
src/post/index/components/post-list-item.vue<修改>
<template> <div class="post-list-item"> <h3> <router-link :to="{ name: 'postShow', params: { postId: item.id } }"> {{ item.title }} </router-link> </h3> - <small>{{ item.user.name }}</small> </div> </template>
修改一下内容列表项目组件的模板,用 router-link 组件包装一下内容的标题,然后给这个组件的 to 属性绑定一个值,它是一个对象,用 name 设置路由的名字,用 params 设置地址参数。
4:预览
先访问一下内容列表 /posts,你会发现列表项目标题现在会是一个链接,链接的地址就是当前这个内容项目所属的内容页面。
点击内容列表项目的标题,会打开对应的内容页面,注意观察浏览器的地址栏里的地址。
项目代码
https://github.com/ninghao/ninghao-vue-dev-3/tree/router
参考课程:Vue.js(v3)前端应用
Vue 3 系列课程正在陆续发布。基于 Node.js 开发服务端应用的课程已经全部放出,里面介绍了几种开发语言,工具,数据库,应用接口的设计与开发思路等等,你可以用这个系列课程作为应用的入门课程。
现在订阅宁皓网,即刻在线学习。