㈠ watch和computed的區別
計侍衡余算屬性通常依賴於其他數據屬性。對於依賴屬性的任何改變都會觸發計算屬性的邏輯。計算屬性基於它們的依賴關系進行緩存,因此只有當依賴項發生變化時,它們才會重新運行,否則他會使用緩存中的屬性值。(例如,返回 new Date()的計算屬性將永遠不會重新運行,因為邏輯將不會運行超過一次)。計算屬性在默認情況下是getters,但是如果需要實現類似的功能,則可以設置setter函數。
計算屬性將被混入到 Vue 實例中。所有 getter 和 setter 的 this 上下文自動地綁定為 Vue 實例。
watch:
watch用來監聽當一個數據屬性值發生變化時,就可以調用的函數,沒有必須依賴的數據屬性;屬於非同步操作;
Vue 實例將會在實例化時調用 $watch(),遍歷 watch 對象的每一個屬性。
舉個攔舉栗子
但數據量較大的時候,用watch更合適;在過濾數據的時候用computed。
computed的基礎用法:
計算屬性的getter函數---當其依賴的屬性的值發生變化的時,這個計算屬性的值也會自動更新。多用於"data,computed"的屬性。
計算屬性的setter函數---當賦值給計算屬性的時候,將調用setter函數。多用於在模板組件中需要修改計算屬性自身的值的時候,例子如下:
計算屬性的緩存---Vue實例中被觀察的數據屬性發生了改變時老滾才會重新執行getter,但是我們有時候計算屬性依賴實時的非觀察數據屬性,比如下面例子中的Data.now
計算屬性getter不執行的場景---當包含計算屬性的節點被移除並且模板中其他地方沒有再引用該屬性的時候,那麼對應的計算屬性的getter函數方法不會執行
在v-for中使用計算屬性,起到類似"過濾器的作用",例子如下:
watch與computed的set函數的比較---uex 接收 的computed ,用set監測不到變化,必須要用watch才可以生效;(原理:實質沒有改變computd的值,只是改變了get的return值 => 組件外的訪問)
v-model 改變的computed,用watch監測不到變化,必須要用computed對象中的set函數方法才能監測得到(原理:相當於每次改變了computed自身的值 => 組件內的訪問)
computed和watch都不可用箭頭函數,因為箭頭函數綁定了父級作用域的上下文,所以 this 將不會按照期望指向 Vue 實例,this.a 將是 undefined。
父組件通過props向子組件傳入的值,在子組件中是不可修改的,不然會報錯,但是如果需要根據頁面需求對props傳入的值進行修改的話,則可以在data中重新定義一個變數,改變指向,通過watch來監測props值的改變,並實時修改data中變數的值,例子如下:
這里 watch 的一個特點是,最初綁定的時候是不會執行的,要等到 firstName 改變時才執行監聽計算。
那我們想要一開始就讓他最初綁定的時候就執行改immediate: true。
handler,Vue.js會去處理這個邏輯,最終編譯出來其實就是這個handler。
deep的意思就是深入觀察,監聽器會一層層的往下遍歷,給對象的所有屬性都加上這個監聽器,但是這樣性能開銷就會非常大了,任何修改裡面任何一個屬性都會觸發這個監聽器里的 handler。
舉個栗子:
㈡ vue.js中,什麼時候用methods什麼時候用computed什麼時候用watch
1、methods是個方法,比如你點擊事件要執行一個方法,這時候就用methods,
2、computed是計算屬性,實時響應的,比如你李源鉛要根據data里一個值隨時變化做出一些處理,就用computed。
3、舉一個例子幫助理解:
1)裂嘩<div id="root">;
2) </div>;
3) <script> var vm = new Vue({ el: '#root', data:data, methods:{
4)method_now(){ return Date.now();} },
5)computed:{
6)computed_now: function () { return Date.now();}} })
7)</script>
4、控制台訪問:
1)$vm0.computed_now;
2)1491741921719$vm0.computed_now;
3)1491741921719$vm0.computed_now;
4)1491741921719$vm0.computed_now;
5)1491741921719$vm0.method_now;
6)()1491741949941$vm0.method_now;
7)()1491741950734$vm0.method_now;
8)()1491741951445$vm0.method_now;
9)()1491741952117。
5、methods是方法和原生js沒區別,大多是需要我們主動調用(比如事件)。
6、computed是get 這個get有點特殊,只要觸發所依賴數據的set會自動觸發get。我們哪好只關心get的return set由系統觸發或者依賴的數據觸發,官方說依賴緩存只是為了理解。其實Date.now()這種只是系統不能觸發set,不能觸發set get當然不會通知觀察者。
7、watch 是set 由data觸發,我們可以在set里進行自己的條件封裝。
㈢ vue怎麼學
如果你是 Vue 開發新手,可能已經聽過很多行話術語,比如單頁面姿畝激應用程序、非同步組件、伺服器端渲染,等等。你可能還聽說過與 Vue 有關的一些工具和庫,比如 Vuex、Webpack、Vue CLI 和 Nuxt。
浸沒在術語和工具的浩瀚海洋中難免會令人感到沮喪,但其實並不是只有你一個人有這種感受,所有經驗水平的開發人員都會持續感覺到這種莫名的壓力。分享一張圖給你看看
基礎知識:
vue的生命跡襪周期: beforeCreate/created、 beforeMount/mounted、 beforeUpdate/updated、 beforeDestory/destoryed
vue常用指令: v-for、 v-bind(縮寫形式 :prop)、 v-on(縮寫形式 @click=』sss')、 v-if/v-else/v-else-if、 v-model、 v-once、 v-html、 v-show...
vue自定義組件: Vue.component(『componentName',{ props:[『p1』,』p2』], template: 『<li>{{ p1 }}</li>'})
vue常用實例方法和屬性: data/$data、 methods/$methods、 $el、 computed(計算屬性)、 $watch、 $set、 $event、 $emit...
如果需要更新的屬性需要緩存,則使用計算屬性的方式,否則可以使用 methods里的方法來更新屬性( methods里的方法每次重新渲染都會執行)
計算屬性默認提供了 getter,你還可以給它設耐友置 setter
當你數據變化是非同步或者開銷較大時,可以使用 watch偵聽器來響應數據的變化
v-bind:class的值可以是一個對象,可實現類似 react中 classnames模塊的功能
自定義組件上的 class會被渲染拼接到 template的根節點的 class屬性上(自定義組件上可使用 v-bind:class來做class的判斷顯示邏輯)
v-bind:style可以用來綁定內聯樣式,這個內聯樣式的值可以由一個對象來定義(類似css in js的模式),且可以被定義為數組(多個樣式對象)
v-bind:style可以使用多重值的形式: <div:style=「display:[『-webkit-box』,』-ms-flexbox』,『flex']"></div>
v-if/v-else/v-else-if的時候,可以用key來管理可復用的元素
v-if是』真正』的渲染,它會確保在切換條件過程中條件塊內的元素的事件監聽器和子組件適時的銷毀和重建
v-if是惰性的,初始為假,什麼也不做,直到為真的時候才渲染元素
v-show總是渲染元素,只是簡單的進行切換
v-if的切換開銷大, v-show則是初始渲染開銷大,頻繁切換使用 v-show,運行時經常改變則使用 v-if
v-if和 v-for一起使用時, v-for的優先順序更高
v-for可遍歷數組,第二個參數是索引
v-for可遍歷對象,第二個參數是 key,第三個參數是索引
v-for和 <template>搭配可減少渲染次數
v-for和自定義組件使用時,需要使用 props來傳遞值
盡可能的為遍歷子元素加上 key,獲得渲染優化
數組變異方法: push/pop/unshift/shift/splice/sort/reverse改變原始數組
數組非變異方法: filter/concat/slice 不改變原始數組,總是返回新數組
Vue不能檢測到數組索引賦值(使用 vm.$set解決)和修改 length長度賦值(使用 splice解決)的情況
Vue不能檢測對象屬性的添加和刪除(使用 vm.$set或 Object.assign)
is=「todo-item」這種屬性的寫法比較適合DOM模板
事件修飾符,它們可串聯使用: .stop、 .prevent、 .capture、 .self、 .once、 .passive(尤其適合移動端)
.passive不用同時和 .prevent使用,後者會被忽略
按鍵修飾符: .enter、 .tab、 .delete、 .esc、 .space、 .up、 .down、 .left、 .right
系統按鍵修飾符: .ctrl、 .alt、 .shift、 .meta(⌘|⊞|◆)、 .exact(允許精確控制系統修飾符組合鍵觸發)
滑鼠修飾符: .left、 .right、 .middle
v-model會忽略表單元素的 value、 checked、 selected,僅僅使用實例中的數據作為數據源
表單事件修飾符: .lazy、 .number、 .trim
組件是可復用的vue實例,具有vue實例大多數屬性和方法
組件可復用,每個組件有獨立的空間
組件上的data必須是一個函數,這樣做避免影響了其他組件
通過 Vue.component()全局注冊的組件可在其被注冊後的任何通過 newVue()創建的實例所使用,包含其組件樹中的所有組件
通過插槽 <slot>分發內容(其實就是類似於react的children)
動態組件 <component>配合屬性 is來實現
解析DOM模板時需要注意下可能會有不生效的情況,需要使用is來傳遞組件
㈣ vue是如何避免重復渲染的
上一篇 vue雙向綁定原理源碼解析
上一篇文章我們說了vue雙向綁定原理,每個watcher對象都綁定了唯一的id,當組件props和data對象屬性發生變化時,將會攜虛觸發watcher對象update方法,
lazy屬性是避免computed屬遲散性里用到(props和data)對象屬性變化導致的重復調用update
默認情況下watcher對象的sync是false,會調用queueWatcher方法
這個方法里主要判斷了當前工作隊列中是否已經有這個watcher對象,辯旦燃
如果工作隊列中沒有此而且隊列也還沒開始執行,加到隊列中去。
如果工作隊列中沒有watcher對象,但是隊列已經開始執行,如果插入位置小於等於當前正在執行的warcher位置,則插入當前的執行warcher的後面。如果插入位置大於當前正在執行的warcher位置,則比較執行位置index後面watcher的id 和 傳入watcher的id
nextTick是非同步執行方法,vue對此進行了封裝,針對不同瀏覽器對js原生非同步的函數的支持,簡單點理解就是一個setTimeout方法
因為是非同步執行方法,所以在主線程的方法執行完,才執行任務隊列中flushSchelerQueue,
下面我們來看一個列子:
測試下來name屬性變化了三次,但是只觸發了一次更新。我們來分析一下原因:
name屬性第一次改變時,queue中插入 name屬性里Dep對象下的所有watcher對象,因主線程函數並沒執行完,此時flushSchelerQueue方法還在等待
name屬性第二次改變時,queue中並沒有插入name屬性里Dep對象下的所有watcher對象,此時flushSchelerQueue方法還在等待
name屬性第三次改變時,queue中還是沒有插入name屬性里Dep對象下的所有watcher對象,此時主線程函數執行完畢,回調任務隊列中flushSchelerQueue方法,更新視圖