vue-router路由之路-极简教程

01、什么是前端路由?
前端路由的一个大背景就是当下流行的单页应用SPA,一些主流的前端框架,如vue、react、angular都属于SPA,那什么是SPA呢?
1.1、SPA
SPA(single-page application)单页面应用,就是浏览器只加载了一个URL地址,一个页面,应用的所有功能、交互都在这个页面内进行。而实现单页面应用的基础就是ajax
,通过异步请求动态的切换页面内容、实现交互,页面整体没有刷新。这避免了页面URL跳转,用户体验也不会中断,就像原生应用一样,体验比较好。越来越多的系统在使用SPA,尤其是WebApp中使用广泛。
与SPA
单页应用对应的就是多页应用MPA
,当然两者不是非此即彼的,主要基于业务需求,是可以共存的。
区别 | 单页面应用(SPA) | 多页面应用(MPA) |
---|---|---|
页面组成 | 一个主页,包含多个页面片段 | 多个主页面 |
刷新方式 | 局部刷新 | 整页刷新 |
url模式 |
hash 哈希模式 、history 历史模式 |
history 历史模式 |
SEO搜索引擎优化 | 难实现,采用页面静态化方式优化 | 容易实现 |
数据传递 | 同一应用内,容易 | 通过url、cookie、localStorage等传递,复杂 |
渲染性能 | 首次加载资源多稍慢,切换快,体验良好 | 切换加载资源,速度慢,用户体验差 |
转场动画 | 容易实现 | 好像实现不了 |
维护成本 | 相对容易 | 相对复杂 |
SPA的主要表现就是更新视图而不重新请求页面,要实现前端的页面的自主路由控制,而不会刷新页面,涉及两种主流的技术:hash
模式、history
模式,这算是前端路由的核心原理,简单了解一下吧!
1.2、#hash路由原理
hash
( /hæʃ/ )是URL地址中#号后面的内容(包括#),原本的作用是用于HTML页面内部定位的描点,描点的变化不会导致页面重新加载。HTTP请求中也不会带#,所以刷新也不影响,这是浏览器端的本地行为。
-
页面不刷新:
hash
的变化不会刷新页面,只会触发浏览器定位锚点,这是hash
实现前端路由的基本原理。 -
获取
hash
:window.location.hash
-
hash
变更事件:window.hashchange
监听hash
变化。 - 不同的
hash
会进入浏览器历史记录。
所以,实现过程就比较简单了!
❶ 监测hash变化:通过hashchange
事件监测hash
变化 。
❷ 加载资源:根据hash
值匹配不同资源进行加载、切换,在Vue中切换的其实就是不同的组件。
🌰hash-简易路由示例:codepen
1.3、history路由原理
history 是历史对象,存放当前文档页面(或框架)的会话历史记录(不是浏览器的所有历史记录)。
history 属性/方法 | 描述 |
---|---|
length | 会话历史列表的记录数量 |
state | 表示历史堆栈顶部记录的状态值,可以是任意可序列化JavaScript对象,限制为2MB |
pushState(stateObj, title[, url]) | 向当前会话的历史堆栈中添加一条记录 |
replaceState(stateObj, title[, url]) | 修改 history 对象的当前(栈顶)记录 |
back() | 返回到(历史列表中)上一个URL地址。 |
forward() | 前进,加载(历史列表中)下一个URL地址 |
go(number) | 加载指定相对当前网页索引位置的历史列表URL地址,go(-1)等同于back() |
pushState
、replaceState
是HTML5在history
上新增的API,用来新增、修改当前文档的历史记录,这两个API就是用来实现SPA单页应用前端路由的关键。他们的参数相同:(stateObj, title[, url])
-
state:一个关联历史会话记录的状态对象,主要作用是在触发
popstate
事件时作为参数传递,不需要可以为null,通过history.state
可以获取到当前会话的state
。 - title:新页面的标题,大部分浏览器都没有管他,可以空着。
-
url:网址,可以相对、绝对地址,但不可跨域。这个
url
会更新到浏览器地址栏,但并不会加载该url
地址,也不检查是否存在,页面也不会刷新!对,要的就是你不刷新。
基于这两个API的特性来实现前端路由。用 pushState
还是 replaceState
呢?两者作用一样的,唯一的不同就是pushState
会产生历史记录,可用于前进、后退。
① 监测url地址变化,
-
popstate
事件:当state
变化时触发该事件,在事件中获取当前url
地址。pushState、replaceState并不会触发popstate
事件,前进、后退、跳转才会触发。 -
点击事件:绑定导航按钮的
click
事件,pushState()
更新url
。
② 加载资源:根据url
值匹配不同资源进行加载、切换。
📢注意,页面第一次加载的时候,不会触发
popstate
事件。
history-简易路由示例:codepen
📢 刷新页面时会重新加载当前(本地路由的)
url
地址,可能就404了,这就需要服务端支持,修改下nginx代理也是可以解决的。
❗history与hash的主要区别,就是不会出现一个#
,看上去更加美观?好像也没啥区别吧!
02、开始vue-router
2.1、简介
Vue Router是Vue官方推出的路由组件,与Vue深度集成,支持hash
、history
两种模式。
-
Vue2.*
版本 ▶ 对应vue-router3.*
版本,vue-router3.* 中文文档 -
Vue3.*
版本 ▶ 对应vue-router4.*
版本,vue-router4.* 中文文档
2.2、安装使用
- 通过
标签直接引用
vue-router.js
:
// 注册插件
Vue.use(VueRouter);
- 通过
vue-cli
脚手架搭建vue
的开发框架,集成了vue-router
组件。 - 注册插件:
Vue.use(VueRouter)
03、vue-router3入门
3.1、Router选项
✔️Router选项 | 描述 |
---|---|
routes | 路由记录配置信息,Array
|
mode | 路由模式,默认hash ,选项:hash 、history 、abstract(NodeJS环境) |
base | url的基本路径,"/app/" ,只有history模式有效? |
linkActiveClass |
激活的class 名称,默认值为router-link-active
|
linkExactActiveClass | 精确匹配激活的class ,默认值为router-link-exact-active ( exact /ɪɡˈzækt/ 精确) |
scrollBehavior | 路由切换完成后的滚动行为回调,函数 Func(to, from, savedPosition)
|
parseQuery/stringifyQuery | 自定义查询字符串的解析/反解析函数 |
//创建路由器
let vrouter = new VueRouter({ routes: vroutes, mode: 'hash', base: '/vsystem/' });
✔️routes.routeRouteConfig
|
初始化时配置用的路由记录RouteConfig ,在后续代码中使用的为路由对象
|
---|---|
path | 路由url路径 path: '/user'
|
component | Component 组件,可用函数方式import 懒加载组件,提高初始化的性能 |
components | 命名视图组件,当有多个命名视图 时,也要配置对应的组件 |
name | 给路由取个名字,自己用,没其他用途,可作为显示的中文标题 |
redirect | 重定向路由,重定向到另外的path、route。如果带有query会解析路由出错? |
alias | path的别名,可一个或多个(数组Array )别名,渲染组件一样 |
parent | 父级路由,根级的parent 为undefined
|
children | 子路由Array ,组件内用 组件作为嵌套组件的容器 |
props | 用于给Vue组件参数Props 传值:boolean | Object | Function- true:自动传递动态路径参 route.params ;- 对象,函数:把它们的结果赋值给组件props参数(按key) |
beforeEnter(to, from, next) | 执行路由前的一个钩子,私有的钩子,目的同全局的守卫钩子beforeEach
|
meta | 路由元信息,自定义的个性化配置,在路由钩子中可以访问处理。meta:{title:'注册'}
|
✔️运行态的 $route 路由对象 |
组件内this.$route 访问,钩子函数、导航函数中的to、from、location都是此路由对象 |
---|---|
path | 路由url路径 |
fullPath | 解析后的完整url,包含query |
params | 存放动态路径参数,{key:value }对象,组件内使用this.$route.params.id
|
query | url查询参数,{key:value }对象 |
hash | 当前路由的哈希hash 值 |
name | 路由名称 |
meta | 元数据记录 |
matched | 匹配到的路由记录列表 |
interface RouteConfig = {
path: string,
component?: Component,
name?: string, // 命名路由
components?: { [name: string]: Component }, // 命名视图组件
redirect?: string | Location | Function,
props?: boolean | Object | Function,
alias?: string | Array,
children?: Array, // 嵌套路由
beforeEnter?: (to: Route, from: Route, next: Function) => void,
meta?: any,
// 2.6.0+
caseSensitive?: boolean, // 匹配规则是否大小写敏感?(默认值:false)
pathToRegexpOptions?: Object // 编译正则的选项
}
//$route路由对象
{
name: "user-box", // 路由名称
fullPath: "/user/21/vip?key=admin",
hash: "", // 当前路由的哈希
matched: [{… }],
meta: {},
params: { id: '21', type: 'vip' },
path: "/user/21/vip",
query: { key: 'admin' }
}
🌰简单的示例:
{{r.name}}
' } },
{ path: '/login', name: '登录', component: { template: '
' } }];
//创建路由器
let vrouter = new VueRouter({ routes: vroutes, mode: 'hash', base: '/vsystem/' });
//app
let app = new Vue({
el:"#app",
router: vrouter,
})
3.2、router实例-创建Router()
✔️router实例-属性 | 描述 |
---|---|
app、apps | Vue根实例,所有apps实例 |
options | 参数选项 |
currentRoute | 当前激活的路由信息对象 |
mode | 路由模式:"hash" | "history" | "abstract" |
START_LOCATION | 初始导航的路由地址,route对象 |
✔️Router实例-方法 | 描述 |
全局的导航守卫 | beforeEach、beforeResolve、afterEach |
编程式导航 | push(route)、replace(route)、go(index)、back()、forward() |
resolve() | ❓解析目标位置 |
addRoute(parent?, RouteConfig) | 添加路由记录、子路由,还有批量添加的addRoutes(routes)
|
getRoutes() | 获取所有活跃的路由记录列表 Array
|
onReady(callback,errorback) | 完成初始化后调用,初始化错误则调用errorback |
onError(callback) | 路由过程中出错时触发,算是一个全局路由异常捕获 |
- 注册插件:
Vue.use(VueRouter)
- 创建全局共享的
router
路由器实例,并配置路由记录。 - 注入
router
,在根Vue组件上注入router
实例,然后所有地方都可以用this.$router
访问了. - 用
显示路由导航,
显示组件视图。 - 愉快的使用了,在Vue组件中访问路由的几种途径:
-
this.$router
,Vue中任意地方可以访问的路由器。 -
this.$route
,组件所属的route
路由对象。
-
🌰创建一个路由:
3.3、path路径:string
path
为路由的地址,当浏览器url
地址与path
匹配时,就会激活当前route路由对象,并显示器对应组件component/components
。
let u1 = { path: '/home', component: Home };
let u2 = { path: '/about', component: About };
let u3 = { path: '/user/register', component: Register };
let u3 = { path: '/*', component: NotFound404 };
//动态路径
let u1 = { path: '/user/:id/:type', component: UserBox }
//匹配的路径
用户1
🔸:
动态路径参数:path
中可以设置动态参数,冒号:
开头,后面的为参数,支持多个顺序组装:path:'/path/:参数1/:参数2'
。这里的参数有什么用呢?
- 参数都会被放到到路由对象
$route.params
中。 - 组件内部直接使用:
$route.params.id
。 - 通过参数专递,设置路由记录
props:true
,参数值$route.params
会传递给组件的参数Props
。
🔸*
通配符:*
通配符匹配任意字符,可放到最后面匹配404,或重定向到默认路由。v4版本里删了,改用正则。
🔸优先级:如果相同的path,匹配哪个呢?按照代码的顺序,先到先得。
3.4、router-link/router-view
✔️
|
描述 |
---|---|
to | path,路由的目标地址,字符串、路由对象。 |
replace | 默认false =push ,执行导航是用replace ,还是push ,对应history 的两个Api |
append❓ | 是否添加基路径base ,默认false
|
tag | 最终渲染的的标签,默认a 。v4中删掉了,用v-slot实现自定义
|
active-class | 激活的类class名 |
exact | 是否精确匹配连接地址,默认false。就是说默认是模糊匹配连接地址的,只要包含就激活了 |
event | 触发路由的事件类型,默认click 。不怎么常用,v4版本中删掉了 |
v-slot | 作用域插槽,用来接收暴露出来的数据, 支持插槽 |
✔️
|
|
name | 命名视图,当有多个就需要名字了,如切换框架布局。在路由记录components 中配置映射关系 |
文章来源于互联网:vue-router路由之路-极简教程