Vue-Router深入ソース分析:index.js


前言
最近需要は确かに少なくありませんが、しかし自分の学习の力がまだ十分だと感じて、需要に押しつぶされていません.今日、Vue-Routerソースコード解析シリーズの第2編の文章を持ってきました:index.js.
本文
vue-routerクラスで何をしましたか?
index.jsはvue-routerというクラスの主な構造関数なので、内容的には重要です.
画像から分かるように、これはES 6がクラスを宣言する方法であり、vue-routerソースコードのクラスの宣言はすべてクラスESの文法を使用し、constructor (options: RouterOptions = {})、vue-routerでflowを使用している.jsはタイプのチェックをしましたが、
何がflow?js?flow.jsはどのように使いますか?紙面の都合上、ここではしばらく触れません.皆さん、公式サイトを参照してください.https://flow.org/en/docs/types/
解析:constructor
まずconstructor内のコードを見てみましょう
constructor (options: RouterOptions = {}) {
    this.app = null
    this.apps = []
    this.options = options
    this.beforeHooks = []
    this.resolveHooks = []
    this.afterHooks = []
    this.matcher = createMatcher(options.routes || [], this)
    //   hash  
    let mode = options.mode || 'hash'
      //      history   h5 pushState           , options  fallback   true     hash  
      //       
    this.fallback = mode === 'history' && !supportsPushState && options.fallback !== false
    if (this.fallback) {
      mode = 'hash'
    }
    if (!inBrowser) {
      mode = 'abstract'
    }
    //  fallback        ,node    abstract  
    this.mode = mode

    switch (mode) {
      case 'history':
        this.history = new HTML5History(this, options.base)
        break
      case 'hash':
        this.history = new HashHistory(this, options.base, this.fallback)
        break
      case 'abstract':
        this.history = new AbstractHistory(this, options.base)
        break
      default:
        if (process.env.NODE_ENV !== 'production') {
          assert(false, `invalid mode: ${mode}`)
        }
    }
  }

vue-routerインスタンスを宣言するときはどうしますか?
let router = new Router({
    base : '/',
    mode : 'history',
    routes : [{
        component : xxx,
        path : xxx
    },xxx]
})
constructor (options: RouterOptions = {}) 
options             ,   base、mode、routes   

このとき、optionsは何なのか知っています.内部でoptionsをどのように処理したかを見てみましょう.
まずvue-routerの最も核心的な内容の一つについてお話しします.
解析:mode
vue-routerのルーティングには2つの方法があることを知っています.1つは#アンカー性で、2つ目は正常なパスと同じですが、vueが構築したアプリケーションは1つですが、ページアプリケーションはどのように彼を正常なマルチページアプリケーションのようにして、パスを変え続けていますか.ここではhtml 5のhistoryのpushStateとreplaceState(ページをリフレッシュしないようにする変更経路)を使用していますが、具体的には公式サイトのドキュメントと大神張鑫旭のブログ(https://www.zhangxinxu.com/wordpress/2013/06/html5-history-api-pushstate-replacestate-ajax/)
vue-routerソースコードには、vue-routerがmodeにどのようにマッチしているかを見てみましょう.
// vue-router    hash  
let mode = options.mode || 'hash';
this.fallback = mode === 'history' && !supportsPushState && options.fallback !== false
//      history  pushState            
//          history.pushState             hash       。
// (options.fallback    true)
//          ,   hash    
    if (this.fallback) {
      mode = 'hash'
    }
//           abstract  ( node  )
    if (!inBrowser) {
      mode = 'abstract'
    }
    this.mode = mode
//                  。
//     mode          。
// HTML5History、HTML5History、HTML5History          base 
//                            。
    switch (mode) {
      case 'history':
        this.history = new HTML5History(this, options.base)
        break
      case 'hash':
        this.history = new HTML5History(this, options.base, this.fallback)
        break
      case 'abstract':
        this.history = new HTML5History(this, options.base)
        break
      default:
        if (process.env.NODE_ENV !== 'production') {
          assert(false, `invalid mode: ${mode}`)
        }
    }

ここまで皆さんは私たちが書いたmodeモードについて少し知っているでしょう.
解析:init
次にinitメソッドについてお話しします.前章では、ルートノードのbeforeCreateライフサイクルフックで、initメソッドを使用しています.
したがってappはルートコンポーネントであり、initは実行前にvue-routerがvueによって正常にuseされたかどうかを判断します.なぜなら、useに成功した後、installメソッドのinstalled属性がtrueに設定されるからです.
init (app: any /* Vue component instance */) {
    process.env.NODE_ENV !== 'production' && assert(
      install.installed,
      `not installed. Make sure to call \`Vue.use(VueRouter)\` ` +
      `before creating root instance.`
    )
    this.apps.push(app)
    // main app already initialized. (         )
    if (this.app) {
      return
    }

    this.app = app

    const history = this.history
    //            vue-router init                  
    //                    ,          
    //                ,   vue-router    
    //                ,    vue-router  popState         ,     ,
    //    ??             ,
    //               ,            。
    if (history instanceof HTML5History) {
      history.transitionTo(history.getCurrentLocation())
    } else if (history instanceof HashHistory) {
      const setupHashListener = () => {
        history.setupListeners()
      }
      history.transitionTo(
        history.getCurrentLocation(),
        setupHashListener,
        setupHashListener
      )
    }
    //        mode(  )
    //  mode   ,     history           ,  instanceof         。

今まで、私たちの前章のinit関数はすでに直列に接続されていましたが、皆さんはどう思いますか?だいぶ気分がよくなりました.
ルーティングガード
vue-routerを使ったことがある学生たちは、ルーティングガードの概念を知っています.これは、ルーティングジャンプの前後など3つの場所に異なるフックを設置し、ルーティングを離れる前に何かをするのに役立ちます.このフックはどうやって作ったのですか?
3つの配列が宣言され、各サイクル内のフックにバインドされた関数が格納されます.
vue-routerグローバルレベルのbeforeEach、beforeResolve、afterEachは何をしましたか?
この2行のコードを信じる勇気がありますか?私もあなたがこんなことをしたことに悩んでいます.registerHook関数を実行して、字面の意味から見ると登録フックです.
どうやって登録したのですか?
function registerHook (list: Array, fn: Function): Function {
  list.push(fn)
  //       function
  return () => {
    const i = list.indexOf(fn)
    if (i > -1) list.splice(i, 1)
  }
}

ライフサイクルのフック配列を受信し、私たちが実行する関数を配列内に転送すると登録が完了します.私はまだこの3つの配列の内容を見ていませんが、直感は私に観察者モード(後で探求する)可能性が高いことを教えてくれました.ここまで登録すればOKなはずなのに、
なぜ戻り値があるのですか?戻り値の内容は一見フック内の関数がはっきりしていますね.このregisterHook関数を呼び出すと、登録関数のクリア関数が得られます.クリアはフック配列に対応する関数で、牛の1匹です.(コードに閉パッケージの使い方を教えてもらう~)
vue-routerのプログラミングナビゲーションはどのようにしますか?
pushメソッドはreplace,goメソッドと対応するルーティング変換インスタンスを呼び出す対応メソッドであり,異なるモードではメソッドが異なるに違いないが,backとforwardはgoメソッドが特殊なパラメータを伝達するので,historyというインスタンスの内容が重要であることが分かった.
声を澄ます
ここまでvue-routerのメインラインの流れを整理しましたが、皆さんはこの内容に満足していますか?気に入らなければブレードを郵送しないでください.
ここまで簡単にまとめてみましょう
1:modeは、hash、history、abstractの3つのモードが設定され、各モードはvue-routerインスタンスのhistoryが異なり、3つの異なるクラスから、各クラスは全体のbaseクラスに継承されます.2:initメソッドはコンポーネント全体を初期化し、vue-routerのインスタンスにappプロパティ格納ルートコンポーネント(これは確かに役に立ちます)、手動で初期化が完了した後の最初のルーティングジャンプを設定します.3:beforeEach、beforeREsolve、afterEachの3つのグローバルなフックには対応するフック関数の配列があり、周期ごとにフック内でやるべきことを格納し、registerHookメソッドを使用してフック関数の登録を完了し、registerHookもフック内の対応する関数をクリアすることができます.4:push,replace,goなどのメソッドはhistoryメソッド内の対応メソッドを用いる.
総括して私たちは何を学びましたか?historyは本当に重要です.私は彼の内部の実現をよく見なければなりません.
本当に情けないまとめです.
vue-routerクラスにはoptionsの一部があります.routesの処理
options.routes    [{path : 'xxx',components : 'xxx'}]     

optionsに基づいて生成する.routesの1部の対比プログラム、プログラムの対比を完成します.
次号の内容はindexの勉強を続けます.jsと開墾historyの中で1つの選択を行って、具体的にどんな内容ですかみんなは積極的に伝言を残して、方向をあげます.
終わりの言葉
フロントエンドer(boy and girl)は一人で戦っているわけではありません.
手配!!!