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


模板中的插入變量是如何渲染到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

圖片描述


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM