下面Vue.js教學欄位帶大家了解vue中的資料初始化(initState)。有一定的參考價值,有需要的朋友可以參考一下,希望對大家有幫助。
資料初始化
#Vue 實例在建立的時候會執行一系列的初始化操作,而在這些初始化操作裡面,和資料綁定關聯最大的是initState。
首先,來看他的程式碼:
function initState(vm) { vm._watchers = []; var opts = vm.$options; if(opts.props) { initProps(vm, opts.props); //初始化props } if(opts.methods) { initMethods(vm, opts.methods); //初始化methods } if(opts.data) { initData(vm); //初始化data } else { observe(vm._data = {}, true /* asRootData */ ); } if(opts.computed) { initComputed(vm, opts.computed); //初始化computed } if(opts.watch && opts.watch !== nativeWatch) { initWatch(vm, opts.watch); //初始化watch } }
在這麼多的資料的初始化中,props、methods和data是比較簡單的(所以我就不詳細介紹了☺) ,而computed 和watch則相對較難,邏輯較複雜,所以我下面主要講下computed 和watch(以下程式碼部分為簡化後的)。
initState裡面主要是對vue實例中的 props, methods, data, computed 和 watch 資料進行初始化。
在初始化props的時候(initProps),會遍歷props中的每個屬性,然後進行型別驗證,資料監測等(提供為props屬性賦值就拋出警告的鉤子函數)。
在初始化methods的時候(initMethods),主要是監測methods中的方法名稱是否合法。
在初始化data的時候(initData),會執行 observe 函數深度遍歷資料中的每一個屬性,進行資料劫持。
在初始化computed的時候(initComputed),會監測資料是否已經存在data或props上,如果存在則拋出警告,否則調用defineComputed函數,監聽數據,為元件中的屬性綁定getter及setter。如果computed中屬性的值是一個函數,則預設為屬性的getter函數。另外屬性的值還可以是一個對象,他只有三個有效字段set、get和cache,分別表示屬性的setter、getter和是否啟用緩存,其中get是必須的,cache預設為true。
function initComputed(vm, computed) { var watchers = vm._computedWatchers = Object.create(null); for(var key in computed) { var userDef = computed[key]; var getter = typeof userDef === 'function' ? userDef : userDef.get; //创建一个计算属性 watcher watchers[key] = new Watcher( vm, getter || noop, noop, computedWatcherOptions ); if(!(key in vm)) { //如果定义的计算属性不在组件实例上,对属性进行数据劫持 //defineComputed 很重要,下面我们再说 defineComputed(vm, key, userDef); } else { //如果定义的计算属性在data和props有,抛出警告 } } }
在初始化watch的時候(initWatch),會呼叫vm.$watch函數為watch中的屬性綁定setter回呼(如果元件中沒有該屬性則不能成功監聽,屬性必須存在於props、 data或computed中)。如果watch中屬性的值是函數,則預設為屬性的setter回呼函數,如果屬性的值是數組,則遍歷數組中的內容,分別為屬性綁定回調,此外屬性的值還可以是一個對象,此時,物件中的handler欄位代表setter回呼函數,immediate代表是否立即先去執行裡面的handler方法,deep代表是否深度監聽。
vm.$watch函數會直接使用Watcher建構觀察者物件。 watch中屬性的值是作為watcher.cb存在,在觀察者update的時候,在watcher.run函數中執行。想了解這個過程可以看我上一篇的 vue響應式系統--observe、watcher、dep中關於Watcher的介紹。
function initWatch(vm, watch) { //遍历watch,为每一个属性创建侦听器 for(var key in watch) { var handler = watch[key]; //如果属性值是一个数组,则遍历数组,为属性创建多个侦听器 //createWatcher函数中封装了vm.$watch,会在vm.$watch中创建侦听器 if(Array.isArray(handler)) { for(var i = 0; i < handler.length; i++) { createWatcher(vm, key, handler[i]); } } else { //为属性创建侦听器 createWatcher(vm, key, handler); } } } function createWatcher(vm, expOrFn, handler, options) { //如果属性值是一个对象,则取对象的handler属性作为回调 if(isPlainObject(handler)) { options = handler; handler = handler.handler; } //如果属性值是一个字符串,则从组件实例上寻找 if(typeof handler === 'string') { handler = vm[handler]; } //为属性创建侦听器 return vm.$watch(expOrFn, handler, options) }
computed
computed本質是一個惰性求值的觀察者,具有快取性,只有當依賴變化後,第一次訪問computed 屬性,才會計算新的值
下面將圍繞這句話來做解釋。
上面程式碼中提到過,當計算屬性中的資料存在與data和props中時,會被警告,也就是這種做法是錯誤的。所以一般的,我們都會直接在計算屬性中聲明資料。還是那個程式碼片段中,如果定義的運算屬性不在元件實例上,會執行defineComputed函數對資料進行資料劫持。下面我們來看看defineComputed函數中做了什麼。
function defineComputed(target, key, userDef) { //是不是服务端渲染 var shouldCache = !isServerRendering(); //如果我们把计算属性的值写成一个函数,这时函数默认为计算属性的get if(typeof userDef === 'function') { sharedPropertyDefinition.get = shouldCache ? //如果不是服务端渲染,则默认使用缓存,设置get为createComputedGetter创建的缓存函数 createComputedGetter(key) : //否则不使用缓存,直接设置get为userDef这个我们定义的函数 userDef; //设置set为空函数 sharedPropertyDefinition.set = noop; } else { //如果我们把计算属性的值写成一个对象,对象中可能包含set、get和cache三个字段 sharedPropertyDefinition.get = userDef.get ? shouldCache && userDef.cache !== false ? //如果我们传入了get字段,且不是服务端渲染,且cache不为false, //设置get为createComputedGetter创建的缓存函数 createComputedGetter(key) : //如果我们传入了get字段,但是是服务端渲染或者cache设为了false,设置get为userDef这个我们定义的函数 userDef.get : //如果没有传入get字段,设置get为空函数 noop; //设置set为我们传入的传入set字段或空函数 sharedPropertyDefinition.set = userDef.set ? userDef.set : noop; } //虽然这里可以get、set都可以设置为空函数 //但是在项目中,get为空函数对数据取值会报错,set为空函数对数据赋值会报错 //而computed主要作用就是计算取值的,所以get字段是必须的 //数据劫持 Object.defineProperty(target, key, sharedPropertyDefinition); }
在上一篇的vue響應式系統--observe、watcher、dep 中,我有關於Watcher的介紹中提到,計算屬性watcher實例化的時候,會把options.lazy設定為true,這裡是計算屬性惰性求值,且可快取的關鍵,當然前提是cache不為false。
cache不為false,會呼叫createComputedGetter函數建立計算屬性的getter函數computedGetter,
先來看一段程式碼
function createComputedGetter(key) { return function computedGetter() { var watcher = this._computedWatchers && this._computedWatchers[key]; if(watcher) { if(watcher.dirty) { //watcher.evaluate中更新watcher的值,并把watcher.dirty设置为false //这样等下次依赖更新的时候才会把watcher.dirty设置为true, //然后进行取值的时候才会再次运行这个函数 watcher.evaluate(); } //依赖追踪 if(Dep.target) { watcher.depend(); } //返回watcher的值 return watcher.value } } } //对于计算属性,当取值计算属性时,发现计算属性的watcher的dirty是true //说明数据不是最新的了,需要重新计算,这里就是重新计算计算属性的值。 Watcher.prototype.evaluate = function evaluate() { this.value = this.get(); this.dirty = false; }; //当一个依赖改变的时候,通知它update Watcher.prototype.update = function update() { //三种watcher,只有计算属性 watcher的lazy设置了true,表示启用惰性求值 if(this.lazy) { this.dirty = true; } else if(this.sync) { //标记为同步计算的直接运行run,三大类型暂无,所以基本会走下面的queueWatcher this.run(); } else { //将watcher推入观察者队列中,下一个tick时调用。 //也就是数据变化不是立即就去更新的,而是异步批量去更新的 queueWatcher(this); } };
當options.lazy設定為true之後(只計算屬性watcher的options.lazy設定為true),每次依賴更新,都不會主動觸發run函數,而是把watcher.dirty設為true。這樣,當計算屬性取值時,就會執行computedGetter函數,computedGetter函數中有一個關於watcher.dirty的判斷,當watcher.dirty為true時會執行watcher.evaluate進行值的更新,並把watcher. dirty設定為false,這樣就完成了惰性求值的過程。後面只要依賴不更新,就不會執行update,就不會把watcher.dirty為true,那麼再次取值的時候就不會執行watcher.evaluate進行值的更新,從而達到了快取的效果。
綜上,我們了解到cache不為false的時候,計算屬性都是惰性求值且具有快取性的,而cache預設是true,我們也大多使用這個預設值,所以我們說 computed本質是一個惰性求值的觀察者,具有快取性,只有當依賴變化後,第一次存取computed 屬性,才會計算新的值
。
相關推薦:
更多程式相關知識,請造訪:程式設計教學! !
以上是詳解vue中的資料初始化(initState)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

Vue.js是前端框架,後端框架用於處理服務器端邏輯。 1)Vue.js專注於構建用戶界面,通過組件化和響應式數據綁定簡化開發。 2)後端框架如Express、Django處理HTTP請求、數據庫操作和業務邏輯,運行在服務器上。

Vue.js與前端技術棧緊密集成,提升開發效率和用戶體驗。 1)構建工具:與Webpack、Rollup集成,實現模塊化開發。 2)狀態管理:與Vuex集成,管理複雜應用狀態。 3)路由:與VueRouter集成,實現單頁面應用路由。 4)CSS預處理器:支持Sass、Less,提升樣式開發效率。

Netflix選擇React來構建其用戶界面,因為React的組件化設計和虛擬DOM機制能夠高效處理複雜界面和頻繁更新。 1)組件化設計讓Netflix將界面分解成可管理的小組件,提高了開發效率和代碼可維護性。 2)虛擬DOM機制通過最小化DOM操作,確保了Netflix用戶界面的流暢性和高性能。

Vue.js被開發者喜愛因為它易於上手且功能強大。 1)其響應式數據綁定係統自動更新視圖。 2)組件系統提高了代碼的可重用性和可維護性。 3)計算屬性和偵聽器增強了代碼的可讀性和性能。 4)使用VueDevtools和檢查控制台錯誤是常見的調試技巧。 5)性能優化包括使用key屬性、計算屬性和keep-alive組件。 6)最佳實踐包括清晰的組件命名、使用單文件組件和合理使用生命週期鉤子。

Vue.js是一個漸進式的JavaScript框架,適用於構建高效、可維護的前端應用。其關鍵特性包括:1.響應式數據綁定,2.組件化開發,3.虛擬DOM。通過這些特性,Vue.js簡化了開發過程,提高了應用性能和可維護性,使其在現代Web開發中備受歡迎。

Vue.js和React各有優劣,選擇取決於項目需求和團隊情況。 1)Vue.js適合小型項目和初學者,因其簡潔和易上手;2)React適用於大型項目和復雜UI,因其豐富的生態系統和組件化設計。

Vue.js通過多種功能提升用戶體驗:1.響應式系統實現數據即時反饋;2.組件化開發提高代碼復用性;3.VueRouter提供平滑導航;4.動態數據綁定和過渡動畫增強交互效果;5.錯誤處理機制確保用戶反饋;6.性能優化和最佳實踐提升應用性能。

Vue.js在Web開發中的角色是作為一個漸進式JavaScript框架,簡化開發過程並提高效率。 1)它通過響應式數據綁定和組件化開發,使開發者能專注於業務邏輯。 2)Vue.js的工作原理依賴於響應式系統和虛擬DOM,優化性能。 3)實際項目中,使用Vuex管理全局狀態和優化數據響應性是常見實踐。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

記事本++7.3.1
好用且免費的程式碼編輯器

VSCode Windows 64位元 下載
微軟推出的免費、功能強大的一款IDE編輯器