前端路由的概念
早期的路由通过后端渲染,使用后端渲染存在性能问题,随之出现了 ajax 技术实现了局部刷新,但是 ajax 并不支持浏览器的前进和后退。
SPA(Single Page Application)中文名为单页面应用程序应运而生,所谓单页面应用程序就是指整个网站只有一个页面,内容的变化通过 ajax 的局部刷新,并且支持浏览器的前进和后退。
SPA 的实现原理:基于 URL 地址的 hash,hash 值的变化会导致浏览器历史记录的产生,但是不会触发新的 url 请求。
要想实现 SPA 最核心的技术就是前端路由。
Vue 官网中的 API 文档就是这样的设计,Vue API
当点击右侧导航树中的内容时,会在地址栏中形成 #...
地址,这串字符被称为 hash
值(下面 demo 中有所提及)。
如下示例:
简易前端路由
组件:
let index = {
template: `<h1>主页</h1>`
}
let info = {
template: `<h1>信息</h1>`
}
let science = {
template: `<h1>科技</h1>`
}
let money = {
template: `<h1>财经</h1>`
}
Vue:
let vm = new Vue({
el: '.container',
data: {
target: 'div-index'
},
components: {
'div-index': index,
'div-info': info,
'div-science': science,
'div-money': money
}
})
HTML:
<div class="container">
<a href="#/index">主页</a>
<a href="#/info">信息</a>
<a href="#/science">科技</a>
<a href="#/money">财经</a>
<component :is="target"></component>
</div>
代码中使用 <component>
标签显示某个组件,使用 v-bind
指令绑定了 is
属性,属性值为要显示的组件。
JS:
// 当地址栏中的 #... 发生变化时,触发该事件
window.onhashchange = function () {
// 可以通过 location.hash 获取变化的 hash 值
// 使用 slice(2) 将前两个 #/ 删除
vm.target = 'div-' + location.hash.slice(2);
}
window.onhashchange
事件,当浏览器地址栏中的 hash 值发生变化时会触发该事件,然后可以使用 location.hash
获取当前的 hash 值,将当前的 hash 值复制给 target 属性值,操作页面发生变化,结果如下:
Vue Router 使用步骤
Vue Router 是 Vue 官方提供的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。
引入 Vue Router 文件要在 Vue 文件之后。
Vue Router 的使用步骤如下:
- 添加路由链接
- 添加路由填充位
- 定义路由组件
- 配置路由规则,创建路由实例对象
- 将路由对象挂载到 Vue 实例
创建第一个 Vue 路由
依据上面使用步骤。
添加路由链接:
<!--
添加路由链接
使用 router-link 设置标签
router-link 标签被解析为 a 标签
router-link 中的 to 属性被解析为 href 属性
-->
<router-link to="/index">点击访问首页</router-link>
<router-link to="/list">点击访问列表</router-link>
浏览器会将上述两个标签解析为 a 标签的形式显示在页面中。如下图:
设置路由填充位
<div>
<h1>before...</h1>
</div>
<!--
添加路由填充位
将匹配的组件渲染在这里
-->
<router-view></router-view>
<div>
<h1>after...</h1>
</div>
上面代码中会将显示的组件插入到 before
和 after
之间。如下图:
上图中显示了 list 组件的原因是在写之前经过了测试,如果是初次打开应该只显示 before 和 after当点击相应的链接时才会显示相应的组件,祥见最后一步的完整效果图
展示图的目的是想要说明路由组件显示的位置就是
router-view
标签所在的位置
定义路由组件
const index = {
template: `<h1>这是 index 组件</h1>`
}
const list = {
template: `<h1>这是 list 组件</h1>`
}
上面代码定义了两个路由组件,这时组件和 router-link
标签之间还没有任何关联,下一步就需要使用 “路由规则” 将两者关联起来。
配置路由规则
// 配置路由规则,创建路由实例
const router = new VueRouter({
// 路由规则数组
routes: [
/*
每个规则都是一个对象,对象中至少包含 path 和 component 属性
path 表示当前规则匹配的 hash 地址,也就是 router-link 中的 to 属性值
component 表示要展示的组件,也就是上面定义的组件
*/
{ path: '/index', component: index },
{ path: '/list', component: list }
]
})
这一步极为关键,将 router-link
标签和路由组件关联了起来,路由对象中的 routes
数组中有路由规则,路由规则中的 path
和 component
必不可少,path
属性中对应 router-link
中的 to
属性,而 component
决定当前的 path 解析哪个路由组件。
挂载到 Vue 实例
let vm = new Vue({
el: '.container',
// 通过 router 属性将路由挂载到 Vue 实例,属性值为创建的规则对象
router
})
由于 ES6 语法的特性,当属性名和属性值相同时,可以写为一个。
若采用 ES5 语法,可以将第 4 行代码写为:router: router
完整效果图: