十四、使用 Vue Router 开发单页应用(1)
本章概要
- 感受前端路由
- HTML 使用路由
- 模块开发使用路由
传统的 Web 应用程序不同页面间的跳转都是向服务器发起请求,服务器处理请求后向浏览器推送页面。
在单页应用程序中,不同视图(组件的模板)的内容都是在同一个页面中渲染,页面间的跳转都是在浏览器端完成,这就需要用到前端路由。
在 Vue.js 中,可以使用官方的路由管理器 Vue Router
14.1 感受前端路由
Vue Router 需要单独下载,也可以直接引用,如下:
<script src="https://unpkg.com/vue-router@next"></script>
如果使用模块化开发,则使用 npm 安装方式,执行一下命令安装 Vue Router。
npm install vue-router@next --save
提示:
注意安装 Vue Router 时,要安装支持 Vue 3.0 的新版本 Vue Router ,即这里的 vue-router@next。支持 Vue 2.x 的 Vue Router 版本名是 vue-router
14.1.1 HTML 使用路由
前端路由的配置有固定的步骤
(1)使用 router-link 组件设置导航链接,代码如下:
<!-- 使用router-link组件来导航 -->
<!-- 通过传入to属性指定链接-->
<!-- <router-link>默认会被渲染成一个<a>标签 -->
<router-link to="/">主页</router-link>
<router-link to="/news">新闻</router-link>
<router-link to="/books">图书</router-link>
<router-link to="/videos">视频</router-link>
to 属性指定链接的 URL ,router-link 默认会被渲染一个 a 标签,如图:
提示:
可以使用 v-slot API 完全定制 router-link 。例如,将 router-link 渲染为 span 标签。代码如下:
<router-link to="/videos" custom v-slot="{ navigate }">
<span @clilck="navigate" @keypress.enter="navigate">视频</span>
</router-link>
<!-- 将渲染为: -->
<span>视频</span>
(2)指定组件在何处渲染,这是通过 router-view 指定,如下:
<router-view></router-view>
单击链接的时候,会在 router-view 所在的位置渲染组件的模板内容,可以把 router-view 理解为占位符。
(3)定义路由组件,代码如下:
// 定义路由组件
// 可以从其他文件import进来
const Home = { template: '<div>主页面</div>' }
const News = { template: '<div>新闻页面</div>' }
const Books = { template: '<div>图书页面</div>' }
const Videos = { template: '<div>视频页面</div>' }
这里只是为了演示前端路由的基本用法,所以组件定义很简单。
(4)定义路由,将第(1)步设置的链接 URL 和组件对应起来。如下:
// 定义路由
// 每个路由应该映射到一个组件。
const routes = [
{ path: '/', component: Home },
{ path: '/news', component: News },
{ path: '/books', component: Books },
{ path: '/videos', component: Videos }
]
(5)创建 VueRouter 实例,将第(4)步定义的路由配置作为选项传递进去。如下:
// 传递routes选项,创建router实例。
const router = VueRouter.createRouter({
//提供要使用的history实现。为了简单起见,在这里使用hash history。
history: VueRouter.createWebHashHistory(),
routes // (简写) 相当于 routes: routes
})
(6)调用应用实例的 use() 方法,传入第(5)步创建的 router 对象,从而让整个应用程序具备路由功能。
const app = Vue.createApp({})
// 使用路由器实例,从而让整个应用都有路由功能
app.use(router)
app.mount('#app')
至此,整个前端路由的配置就完成了,完整代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app">
<p>
<!-- 使用router-link组件来导航 -->
<!-- 通过传入to属性指定链接-->
<!-- <router-link>默认会被渲染成一个<a>标签 -->
<router-link to="/">主页</router-link>
<router-link to="/news">新闻</router-link>
<router-link to="/books">图书</router-link>
<router-link to="/videos">视频</router-link>
</p>
<!-- 路由出口 -->
<!-- 路由匹配到的组件将在这里渲染 -->
<router-view></router-view>
</div>
<script src="https://unpkg.com/vue@next"></script>
<script src="https://unpkg.com/vue-router@next"></script>
<script>
// 定义路由组件
// 可以从其他文件import进来
const Home = { template: '<div>主页面</div>' }
const News = { template: '<div>新闻页面</div>' }
const Books = { template: '<div>图书页面</div>' }
const Videos = { template: '<div>视频页面</div>' }
// 定义路由
// 每个路由应该映射到一个组件。
const routes = [
{ path: '/', component: Home },
{ path: '/news', component: News },
{ path: '/books', component: Books },
{ path: '/videos', component: Videos }
]
// 传递routes选项,创建router实例。
const router = VueRouter.createRouter({
//提供要使用的history实现。为了简单起见,在这里使用hash history。
history: VueRouter.createWebHashHistory(),
routes // (简写) 相当于 routes: routes
})
const app = Vue.createApp({})
// 使用路由器实例,从而让整个应用都有路由功能
app.use(router)
app.mount('#app')
</script>
</body>
</html>
任意单击某个链接,前端路由演示效果如图:
在创建 router 实例时,为选项 history 指定的是 VueRouter.createWebHashHistory() ,也就是 hash 模式,即使用 URL 的 hash (即 URL 中的锚部分,从 “#”开始的部分)模拟完整的 URL ,以便在 URL 更改时不会重新加载页面,如地址栏中的“#videos”的使用。
14.1.2 模块开发使用路由
模块化开发使用前端路由也是遵照 14.1.1节的各个步骤,只是形式上有些变化。
先利用 Vue CLI 创建一个 Vue 3.0 的脚手架项目,项目名为 myrouter,直接选择 Default (Vue 3 Preview)([Vue 3] babel,eslint),开始项目创建。
在 cmd 命令窗口输入:
vue create myrouter
然后使用 Visual Studio Code 打开刚才新建的项目。
(1)为项目安装 vue-router 。选择【终端】——>【新终端】选项,在弹出的终端窗口中输入一下命令安装 vue-router:
npm install vue-router@next --save
(2)在 App.vue 中设置导航链接和组件渲染的位置。修改其模板内容,并将引用 HelloWorld 组件的地方删除。修改后的代码如下:
<template>
<p>
<router-link to="/">首页</router-link>
<router-link to="/news">新闻</router-link>
<router-link to="/books">图书</router-link>
<router-link to="/videos">视频</router-link>
</p>
<router-view></router-view>
</template>
<script>
export default {
name: 'App',
components: {
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
/*text-align: center;*/
color: #2c3e50;
margin-top: 60px;
}
</style>
(3)定义组件路由。在 components 目录下新建 Home.vue、News.vue、Books.vue、Videos.vue 四个文件。代码如下:
Home.vue
<template>
<div>主页面</div>
</template>
<script>
export default {
}
</script>
News.vue
<template>
<div>新闻页面</div>
</template>
<script>
export default {
}
</script>
Books.vue
<template>
<div>图书页面</div>
</template>
<script>
export default {
}
</script>
Videos.vue
<template>
<div>视频页面</div>
</template>
<script>
export default {
}
</script>
(4)单独定义一个模块文件,配置路由信息,这也是项目中经常使用的方式。在 src 目录下新建一个 router 文件夹,在该文件夹下新建一个 index.js 文件。编辑该文件,代码如下:
import { createRouter, createWebHashHistory } from 'vue-router'
import Home from '@/components/Home'
import News from '@/components/News'
import Books from '@/components/Books'
import Videos from '@/components/Videos'
export default createRouter({
history: createWebHashHistory(),
routes: [
{
path: '/',
component: Home,
},
{
path: '/news',
component: News,
},
{
path: '/books',
component: Books,
},
{
path: '/videos',
component: Videos,
}
]
})
(5)在程序入口 main.js 中,使用 router 实例让整个应用都有路由功能。代码如下:
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
createApp(App).use(router).mount('#app')
在基于 Vue.js 的项目开发中,如果要导入一个目录中的 index.js 文件,可以直接导入该目录,内置的 webpack 会自动导入 index.js 文件。
至此,前端路由就已经全部配置完毕。打开终端,输入 npm run serve 命令,运行项目,体验单页应用的前端路由。
启动的时候报以下错误
在 package.sjon 中配置 rules 参数可解决