首页前端开发JavaScript详解vue的hash跳转原理

详解vue的hash跳转原理

时间2024-02-01 02:26:03发布访客分类JavaScript浏览541
导读:收集整理的这篇文章主要介绍了详解vue的hash跳转原理,觉得挺不错的,现在分享给大家,也给大家做个参考。 目录hash和history的区别HashHistorygetCurrentL...
收集整理的这篇文章主要介绍了详解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核实处理,我们将尽快回复您,谢谢合作!

hashvue

若转载请注明出处: 详解vue的hash跳转原理
本文地址: https://pptw.com/jishu/594798.html
js 创建对象的多种方式与优缺点小结 c语言是高级语言吗?

游客 回复需填写必要信息