Vue路由
1.基于 hash 的实现
早期的前端路由的实现就是基于location.hash来实现的。实现原理也很简单就是:监听#后面的内容来发起Ajax请求来进行局部更新,而不需要刷新整个页面。
location.hash的值就是URL中#后面的内容。
例如:https://www.happy.com#me中的 location.hash = ‘#me’
hash也存在下面几个特性:
1.URL中的hash值只是客户端的一种状态,也就是说当向服务器发出请求时,hash部分不会被发送。
2.hash值的改变,都会在浏览器的访问历史中增加一个记录,因此我们能通过浏览器的回退,前进按钮控制hash 的切换。
3.我们可以使用hashchange事件来监听URL的变化
触发hash变化的方式也有两种:
1.通过a标签,并设置href属性,当用户点击这个标签后,URL就会发生变化,也就会触发hashchange事件了
例如:<a href="#hahha">hahha</a>
2.直接使用js来对location.hash进行赋值,从而改变URL 触发hashchange事件
例如: location.hash = '#hahha'
3.浏览器前进后退改变 URL,触发hashchange事件
2.基于 history API 的实现
切换历史状态
包括 back() 、forword() 、go(n) 三个方法,分别对应浏览器的前进,后退,跳转操作
history.go(-2) //后退两次 + 刷新
history.go(2) //前进两次
history.back() //后退 (不刷新)
history.forword() //前进
back() 方法可加载历史列表中的前一个 URL(如果存在)。调用该方法的效果等价于点击后退按钮或调用 history.go(-1)
forward() 方法可加载历史列表中的下一个 URL。调用该方法的效果等价于点击前进按钮或调用 history.go(1)
修改历史状态
包括 pushState() 、replaceState() 两个方法,都接收三个参数:stateObj 、title、url。它们可以在不刷新页面的情况下,操作浏览器的历史记录。
pushState() 新增一个历史记录
replaceState() 替换当前的历史记录
popstate() 事件。用于监听历史记录的变化
参数:
状态对象(state object):一个JavaScript对象,与用 pushState() 方法创建的新历史记录条目关联。无论何时用户导航到新创建的状态,会触发popstate 事件,并能在事件中使用该对象
标题(title):一般浏览器会忽略,传 null 即可
地址(URL):需要新增的历史记录地址,浏览器不会去直接加载改地址,但后面也可能会去尝试加载该地址。此外需要注意的是,传入的URL与当前URL应该是同源的。
3.router
- router-link自定义组件,用于创建链接。可以使 Vue Router 在不重新加载页面的情况下更改 URL,处理 URL 的生成以及编码。
- router-view路由出口,用于显示与 url 对应的组件(路由映射组件),可以放到任何位置。
push() 程序式地通过将一条记录加入到历史栈中来导航到一个新的 URL
resolve() 返回一个路由地址的规范化版本。同时包含一个包含任何现有 base 的 href 属性
replace() 程序式地通过替换历史栈中的当前记录来导航到一个新的 URL
addRoute(parentName, route) 添加一个新的路由记录,将其作为一个已有路由的子路由。
路由守卫
- onBeforeRouteLeave(to, from, next) { } 当前位置的组件离开时被触发。
- onBeforeRouteUpdate(to, from, next) {} 当前位置的组件被更新时触发。
route
route.path 字符串,等于当前路由对象的路径,会被解析为绝对路径,如/home/ews
route.params 对象,包含路由中的动态片段和全匹配片段的键值对,不会拼接到路由的url后面
route.query 对象,包含路由中查询参数的键值对。会拼接到路由url后面
route.name 当前路由的名字,如果没有使用具体路径,则名字为空
route.fullPath完成解析后的 URL,包含查询参数和 hash 的完整路径。
route.matched一个数组,包含当前路由的所有嵌套路径片段的路由记录 。路由记录就是 routes 配置数组中的对象副本 (还有在 children 数组)。
通常会用来做面包屑
route.redirectedFrom如果存在重定向,即为重定向来源的路由的名字
vue路由守卫
1 什么是路由守卫
路由守卫就是路由跳转过程中的一些钩子函数 ,在路由跳转的时候,做一些判断或其它的操作。 类似于组件生命周期钩子函数 。
2 分类
1.全局路由守卫
- beforeEach(to, from, next) 全局前置守卫,路由跳转前触发
- beforeResolve(to, from, next) 全局解析守卫 在所有组件内守卫和异步路由组件被解析之后触发
- afterEach(to, from) 全局后置守卫,路由跳转完成后触发
2.路由独享守卫
beforeEnter(to,from,next) 路由对象单个路由配置 ,单个路由进入前触发
3.组件路由守卫
- beforeRouteEnter(to,from,next) 在组件生命周期beforeCreate阶段触发
- beforeRouteUpdadte(to,from,next) 当前路由改变时触发
- beforeRouteLeave(to,from,next) 导航离开该组件的对应路由时触发
4.参数
to: 即将要进入的目标路由对象
from: 即将要离开的路由对象
next(Function):是否可以进入某个具体路由,或者是某个具体路由的路径
3.详解
1.路由前置守卫 beforeEach(to, from, next)
const router = new VueRouter({ ... })router.beforeEach((to, from, next) => {// ...
})
在路由跳转前触发,在实际项目中应用最多,主要是登陆验证和跳转权限判断
2.全局解析守卫 beforeResolve(to, from, next)
router.beforeResolve((to, from, next) => {// ...
})
类似于路由前置守卫 beforeEach(to, from, next),也是路由跳转前触发,但它是同时在所有组件内守卫和异步路由组件被解析之后触发的
调用时机:在 beforeEach(to, from, next)和组件内beforeRouteEnter(to, from, next)之后,afterEach(to, from)之前调用
3.全局后置守卫 afterEach(to, from, next)
router.afterEach((to, from) => {// ...
})
于路由前置守卫 beforeEach(to, from, next)相对,路由跳转后触发,但它是同时在所有组件内守卫和异步路由组件被解析之后触发的
调用时机:在 beforeEach(to, from, next)和组件内beforeResolve (to, from, next)之后, beforeRouteEnter(to, from)之前调用
4. 路由独享守卫 beforeEnter(to, from, next)
const router = new VueRouter({routes: [{path: '/foo',component: Foo,beforeEnter: (to, from, next) => {// ...}}]
})
于路由前置守卫 beforeEach(to, from, next)相同,但在beforeEach(to, from, next)后触发
5. 组件路由守卫 beforeRouteEnter(to, from, next)
const Foo = {template: `...`,beforeRouteEnter(to, from, next) {// 不能获取组件实例 // 因为当守卫执行前,组件实例还没被创建}
因为该守卫在组件创建之前阶段触发,那个时候组件还没有创建成功,所以这个守卫内不能使用this获取组件实例
调用时机:在全局守卫beforeEach(to, from, next)和独享守卫beforeEnter(to, from, next)之后,全局beforeResolve(to, from, next)和全局afterEach(to, from)之前调用
6. 组件路由守卫 beforeRouteUpdate(to, from, next)
beforeRouteUpdate(to, from, next) {// 在当前路由改变,但是该组件被复用时调用// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。// 可以访问组件实例 },
调用时机:在当前路由复用时
7. 组件路由守卫 beforeRouteLeave(to, from, next)
beforeRouteLeave(to, from, next) {// 导航离开该组件的对应路由时调用// 可以访问组件实例}
}
原来的vue2路由是通过this.$route和this.$router来控制的。
现在vue3有所变化,useRoute相当于以前的this.$route,而useRouter相当于this.$router