1. 程式人生 > >Vue.js源碼全方位深入解析--學習筆記

Vue.js源碼全方位深入解析--學習筆記

scrip stat UNC 導航 resolve 轉化 ansi 渲染 ack

模板中的插入變量是如何渲染到DOM上的?

initMixin(Vue)->_init->$options-> $mount()當執行該掛載方法時DOM變化

為什麽可以通過this訪問到data裏面的數據?

initstate(vm)->initData()->proxy(vm,_data,key)代理函數
所以我們也可以同過this._data.dataName獲取到數據
技術分享圖片

$mount的實現

$mount->處理e(編譯,轉化成render函數)->mountComponent()->updateComponent()->渲染Wather

vm._render的實現

_render->從vm.options拿到render->render.call(vm._renderProxy,vm.$createElement)->initProxy->hasHandler判斷元素如果不在target上,則會報錯warnNonPresent-> 返回vnode

虛擬Dom

  1. VNodeData定義在flow/vnode.js (創建虛擬DomTree)
  2. create-element–>
  3. 參數重載->
  4. _createElement->
  5. 對data校驗(如果是響應式的 return create EmptyVnode() (vnode.js))->
  6. 對children做normalizetionChildren(normalize-chiildren.js) 多維數組變一維數組->
  7. 對tag進行判斷(字符串還是組件)->
  8. 創建Dom

  1. _update定義在src/core/instance/lifecycle.js (渲染

  2. vm.__patch__

  3. patch

  4. createPatchFunction ( 內部定義了一系列的輔助方法,最終返回了一個 patch 方法,這個方法就賦值給了 vm._update 函數裏調用的

    vm.__patch__

    )

    函數柯裏化

    1. createElm (通過虛擬節點創建真實的 DOM 並插入到它的父節點中)
    2. createChildren
    3. invokeCreateHooks

組件化

createCompment

  • createElement
  • _createElement(對Tag判斷)
  • createComponent

技術分享圖片

patch

整體流程
重要屬性
  • activeInstance
  • vm.$vnode
  • vm._vnode
嵌套組件插入順序

Vuex

技術分享圖片

Vue組件

  • 巧用Vue標簽is屬性,解決模板標簽出現bug問題
  • 子組件定義data,必須是一個函數
  • ref 操作dom
  • 父組件通過屬性向子組件傳遞數據

動畫

transition

通過自動操縱transition中的元素的class實現

技術分享圖片

同時使用過渡和動畫

  • 通過設置type=“transition”(過渡)來設置根據過渡還是動畫顯示時長
  • 通過appear實現頁面初試動畫
    <link rel="stylesheet" href="./animate.css">
    <script src="./vue.min.js"></script>
    <style>
      .fade-enter,.fade-leave-to{
        opacity: 0;
      }
      .fade-enter-active,
      .fade-leave-active{
        transition: opacity 3s;
      }
    </style>
</head>
<body>
    <div id="app">
        <!-- type="transition" 放在transition裏面指定指行的時間以animate或者transition為準-->
        <transition
         :duration="{enter: 5000, leave: 10000}"
         name="fade"
         appear
         enter-active-class="animated swing fade-enter-active"
         leave-active-class="animated shake fade-leave-active"
         appear-active-class="animated swing"
        >
        <div v-show="show">hello meijing</div>
        </transition>
        <button @click="handleClick">切換</button>
    </div>

    <script>
    

    var vm = new Vue({
        el: '#app',
        data: {
            show: true
        },
        methods: {
            handleClick: function(){
                this.show = !this.show
            }
        }
    })
    </script>

Js 動畫與 Velocity.js 的結合

    <link rel="stylesheet" href="./animate.css">
    <script src="./vue.min.js"></script>
    <script src="./velocity.min.js"></script>
</head>
<body>
    <div id="app">
        <transition
         name="fade"
         @before-enter="handleBeforeEnter"
         @enter="handleEnter"
         @after-enter="handleAfterEnter"
        >
        <!-- <transition
         name="fade"
         @before-leave="handleBeforeEnter"
         @leave="handleEnter"
         @after-leave="handleAfterEnter"
        > -->
        <div v-show="show">hello meijing</div>
        </transition>
        <button @click="handleClick">切換</button>
    </div>

    <script>
    

    var vm = new Vue({
        el: '#app',
        data: {
            show: true
        },
        methods: {
            handleClick: function(){
                this.show = !this.show
            },
            handleBeforeEnter: function(el){
                el.style.opacity = 0;
            },
            handleEnter: function(el, done){
                Velocity(el, {opacity: 1}, {duration: 1000, complete: done})
            },
            handleAfterEnter: function(el){
                console.log("動畫結束")
            }
        }
    })
    </script>

Router

  • hash路由並不適合SEO
    • mode: ‘history’
  • base 基路徑
  • router路由樣式
    • linkActiveClass 部分匹配
    • linkExactActiveClass 完全匹配
  • historyApiFallback 路徑映射關系
    • 要包含webpack裏的publicPath
  • scrollBehavior 記錄滾動行為
  • parseQuery,stringifyQuery 參數
  • fallback 如果頁面不支持history路由,自動切換Hash方式
  • this.$route獲取當前的路由信息,但是並不是所有的信息都有,所以可以使用meta屬性
  • 同一組件內,不同路由有不同router-view可以使用components替換component,然後給router-view來解決
  • 路由守衛(導航狗子) 可以用來驗證參數
    • beforeEach
    • beforeResolve
    • afterEach 跳轉之後
  • 路由配置狗子
    • beforeEnter
  • 在組件定義狗子
    • beforeRouteEnter
    • beforeRouteUpdate
    • beforeRouteLeave (大表單確認提醒,安全性)
    • 在next之前拿不到this
    • next(vm => {console.log(vm.id)})
  • 異步加載,在進入路由中import引入組件
    • 需要插件 babel-plugin-syntax-dynamic-import

Vuex

  • 註意目錄結構的劃分
  • mapState
    • ...mapState({*** : (state) => state.**})
  • mapGetters
    • ...mapState([‘**‘])
    • mapActions
    • mapMutation
  • mutation只有兩個參數,修改多個數據要用對象,使用this.$store.commit(‘方法名’,{})來觸發
  • action和mutation一樣,不過主要用來做異步修改方法。使用this.$store.dispatch(‘方法名’,{參數})來觸發
  • 模塊化 modules
    • namespaced
  • 異步加載模塊
    • registerModule
    • unregisterModule
  • 熱加載
    -store.watch((state) => {},()=>{})
    當第一個方法返回值有變化的時候才會調用第二個方法
  • store.subscribe(mutation,state)=>{}) 拿到所有mutation的變化,每次變化調用回調函數
  • subscribeAction
  • plugins 在vue初始化的時候定義

SSR

技術分享圖片

Vue.js源碼全方位深入解析--學習筆記