vueのhashジャンプの原理を詳しく説明します。


new vueRouterの時に私達は一つのmode属性を導入できます。彼は三つの値を受け取ります。hash/history/abstract

hashとhistoryの違い
historyのパスはもっと綺麗です。たとえば。http://yoursite.com/user/idhistoryは、ページを再読み込みすることなく、pusState()に基づいてURLジャンプを完了する。しかし、強制更新は問題があります。だから、historyモードはバックエンドの人が協力して使う必要があります。
hashの経路は22166;を持っています。たとえばhttp://yoursite.com#/user/id
ハイビスカス

class VueRouter{
 constructor(options){
  this.matcher = createMatcher(options.routes || []);
//      hash                       
  this.history = new HashHistory(this);//this vue-router   
  }
}
ソースコードはここで基本的なクラスを作成しました。ここでソースコードと統一して、このベースクラスは3つのモード共通の方法と属性を実装しました。ここで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
  )
}
ここでは、それぞれtranition To、get CurrenntLocation、setupListenerを実現します。
get CurrenntLocationが実現しました。

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が変化してビューを更新すればいいです。
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ジャンプの原理に関する資料は他の関連記事に注目してください。