大フロントエンド【3-1-1ノート】手書きVue Router


1、HashモードとHistoryモード
両者の存在表現形式と原理上の違い
1、表現形式の違い
Hash:https://api.aibianxian.net/igameh5/#/detail/213?token=123を選択します.
History: https://api.aibianxian.net/igameh5/detail/213/123
2、原理の違い
Hash:アンカーポイント、およびonHashChangeイベントに基づいて、アンカーポイントの値をルーティングアドレスとして使用し、アドレスが変化するとonHashChangeイベントがトリガーされ、パスに基づいてページに表示される内容が決定されます.
**History:**HTML 5のHistoryAPIに基づく
  • history.pushState()は互換モードが存在し、IE 10以降は
  • をサポートする
  • history.replaceState()

  • PushStateとpushメソッドの違いは、pushを呼び出すと経路が変化し、サーバにリクエストが送信され、pushStateを呼び出すとサーバにリクエストが送信されず、アドレスバーのアドレスのみが変更され、アドレスが履歴に記録され、クライアントルーティングが可能になる
    3、Historyモードの使用
  • Historyサーバのサポートが必要
  • 単一ページアプリケーションでは、サービス側にアドレスが1つも存在せず、404ページ
  • に戻る.
  • は、サービス側で静的リソース以外に、単一ページアプリケーションのindexを返すべきである.html

  • 2、Vueの構築バージョン
    ランタイムバージョンとフルバージョン
    1、ランタイムバージョン
    templateテンプレートはサポートされておらず、パッケージが必要な場合は事前にコンパイルします.render関数を使用できます.vue-cliで作成されたプロジェクトのデフォルトは、効率が高いため、ランタイムバージョンです.
    Vue.component('router-link',{
                props:{
                    to:String
                },
                render(h){
                    return h('a',{
                        attrs:{
                            href:this.to
                        }
                    },[this.$slots.default])
                }
     })
    

    2、完全版
    ランタイムコンパイラruntimeCompilerを含み、体積はランタイム版より10 K程度大きく、プログラム実行時にテンプレートをrender関数に変換し、性能はランタイムバージョンに及ばない.
    3、手書きVue Router
    プロファイル
    1、vue.config.js
    module.exports = {
        //       vue
        runtimeCompiler:true
    }
    

    2、index.js
    // index.js
    let _Vue = null
    export default class VueRouter {
        static install(Vue) {
            // 1、             
            if (VueRouter.install.installed) {
                return
            }
            VueRouter.install.installed = true
            //2、 Vue           
            _Vue = Vue
            //3、   Vue       router     Vue   
            _Vue.mixin({
                beforeCreate() {
                    console.log(this.$options)
                    if (this.$options.router) {
                        console.log(123)
                        _Vue.prototype.$router = this.$options.router
                        this.$options.router.init()
                    }
                }
            })
        }
    
        constructor(options) {
            this.options = options
            this.routerMap = {}
            this.data = _Vue.observable({
                current: "/"
            })
        }
    
        init() {
            this.createRouteMap()
            this.initCommponents(_Vue)
            this.initEvent()
        }
    
        createRouteMap() {
            //  :         ,           routeMap 
            this.options.routes.forEach(route => {
                this.routerMap[route.path] = route.component
            })
        }
    
        initCommponents(Vue) {
            console.log("  ")
        
             // Vue.component('router-link', {
            //     props: {
            //         to: String
            //     },
            //     template: ''
            // })
    
    
            //       
            Vue.component('router-link',{
                props:{
                    to:String
                },
                render(h){
                    return h('a',{
                        attrs:{
                            href:this.to
                        },
                        on:{
                            click: this.clickHandler
                        }
                    },[this.$slots.default])
                },
                methods:{
                    clickHandler(e){
                        //    
                        history.pushState({},'',this.to)
                        //
                        this.$router.data.current = this.to
                        e.preventDefault()
                    }
                }
            })
           
            const self = this
            Vue.component('router-view',{
                render(h){
                    const component = self.routerMap[self.data.current]
                    return h(component)
                }
            })
        }
    
        //            ,        ,  
        initEvent(){
            //popstate            ,  pullState,replaState    
            window.addEventListener('popstate',()=>{
                this.data.current = window.location.pathname
            })
        }
    }