详解vue的hash跳转原理
目录
- hash和history的区别
- HashHistory
- getCurrentLocation实现
- setupListener实现
- TransitionTo实现
- macth方法
在new vueRouter的时候我们可以传入一个mode属性,他可以接收三个值:hash/history/abstract
hash和history的区别
history的路径更美观一点 比如http://yoursITe.COM/user/id,history是基于pushstate()来完成 URL 跳转而无须重新加载页面。 但是强制刷新还是会有问题(服务端来解决这个问题),所以history模式需要后端人员配合使用。
hash的路径会带有#,比如http://yoursite.com#/user/id
HashHistory
class VueRouter{
constructor(options){
this.matcher = createMatcher(options.routes || []);
//这里为了讲解hash模式 所以就不进行判断用户传进来的是哪种模式了 this.history = new HashHistory(this);
//this vue-router的实例 }
}
源码这里创建了一个基类我们这里和源码统一,这个基类封装了三种模式公用的方法和属性,那么我们在这里创建一个HashHistory和基类History
import History From './base'// hash路由export default class HashHistory extends History{
constructor(router){
suPEr(router);
//继承调用父类 等于call }
}
// 路由的基类export default class History {
constructor(router){
this.router = router;
}
}
如果是hash路由,打开网站如果没有hash默认应该添加#/
import History from './base';
function ensureSlash(){
if(window.location.hash){
return }
window.location.hash = '/'}
export default class HashHistory extends History{
constructor(router){
super(router);
ensureSlash();
// 确保有hash }
}
再看一下初始化的逻辑(上面的router.init函数)
init(app){
const history = this.history;
// 初始化时,应该先拿到当前路径,进行匹配逻辑 // 让路由系统过度到某个路径 const SETUPHashListener = ()=>
{
history.setupListener();
// 监听路径变化 }
history.transitionTo( // 父类提供方法负责跳转 history.getcurrentLocation(), // 子类获取对应的路径 // 跳转成功后注册路径监听,为视图更新做准备 setupHashListener )}
这里我们要分别实现 transitionTo(基类方法)、 getCurrentLocation 、setupListener
getCurrentLocation实现
function getHash(){
return window.location.hash.slice(1);
}
export default class HashHistory extends History{
// ... getCurrentLocation(){
return getHash();
}
}
setupListener实现
export default class HashHistory extends History{
// ... setupListener(){
window.addEventListener('hashchange', ()=>
{
// 根据当前hash值 过度到对应路径 this.transitionTo(getHash());
}
) }
}
TransitionTo实现
export function createRoute(record, location) {
// {
path:'/',matched:[record,record]}
let res = [];
if (record) {
// 如果有记录 while(record){
res.unshift(record);
// 就将当前记录的父亲放到前面 record = record.parent }
}
return {
...location, matched: res }
}
export default class History {
constructor(router) {
this.router = router;
// 根据记录和路径返回对象,稍后会用于router-view的匹配 this.current = createRoute(null, {
path: '/' }
) }
// 核心逻辑 transitionTo(location, oncomplete) {
// 去匹配路径 let route = this.router.match(location);
// 相同路径不必过渡 if( location === route.path &
&
route.matched.length === this.current.matched.length){
return }
//更新路由并且下面会提到改变根实例上的_route属性 this.updateRoute(route) onComplete &
&
onComplete();
}
}
export default class VueRouter{
// ... //做一个代理 match(location){
return this.matcher.match(location);
}
}
macth方法
function match(location){
// 稍后根据路径找到对应的记录 let record = pathMap[location] if (record) {
// 根据记录创建对应的路由 //参数:/about/a:{
path:xx,component...}
,path:'/about/a' return createRoute(record,{
path:location }
) }
// 找不到则返回空匹配 return createRoute(null, {
path: location }
)}
我们不难发现路径变化时都会更改current属性,我们可以把current属性变成响应式的,每次current变化刷新视图即可
在install方法中
install(Vue) {
Vue.mixin({
// 给所有组件的生命周期都增加beforeCreate方法 beforeCreate() {
if (this.$options.router) {
//调用Vue类中双向数据绑定方法 Vue.util.defineReactive(this,'_route',this._router.history.current);
}
}
}
);
// $route和$router方法 这两个方法仅仅是vue中最常见的代理 仅仅是为了更加方便 Object.definePRoperty(Vue.prototype,'$route',{
// 每个实例都可以获取到$route属性 get(){
return this._routerRoot._route;
//上面刚进行双向数据绑定的 }
}
);
Object.defineProperty(Vue.prototype,'$router',{
// 每个实例都可以获取router实例 get(){
return this._routerRoot._router;
}
}
) }
切换路由每次初始化时都需要调用更新_route的方法,因为install的时候把_route进行双向数据绑定,刚进来是没有this._router.history.current的,通过发布订阅方式来进行订阅和更新操作;在init方法中增加监听函数
history.listen((route) =>
{
// 需要更新_route属性,出入一个函数 app._route = route}
);
export default class History {
constructor(router) {
// ... this.cb = null;
}
listen(cb){
this.cb = cb;
// 注册函数 }
updateRoute(route){
this.current =route;
this.cb &
&
this.cb(route);
// 更新current后 更新_route属性 }
}
以上就是详解vue的hash跳转原理的详细内容,更多关于vue的hash跳转原理的资料请关注其它相关文章!
您可能感兴趣的文章:- Vue-Element-Admin集成自己的接口实现登录跳转
- Vue项目中实现带参跳转功能
- vue 页面跳转的实现方式
- vue实现登录、注册、退出、跳转等功能
- vue中路由跳转不计入history的操作
- vue中PC端地址跳转移动端的操作方法
声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!
若转载请注明出处: 详解vue的hash跳转原理
本文地址: https://pptw.com/jishu/594798.html
