本文重點知識點速覽:html
- Vue 中的 watch 對象中的回調函數不能是箭頭函數。
- 箭頭函數中的 this 指向的是函數定義時所在的對象,普通函數中的 this 指向的是函數運行時所在的對象。
- 函數的 this 指向問題。
一塊兒學習吧...vue
提及箭頭函數你們必定不陌生,箭頭函數是 ES6 中對函數的擴展,使用起來方便快捷,可能有些小夥伴對箭頭函數不是特別瞭解,因此在這裏先舉個例子吧。npm
// 普通函數定義 function add(a, b) { return a + b; } // 箭頭函數等價定義 const add = (a, b) => { return a + b; } // 普通匿名函數 fucntion() { console.log('hello'); } // 箭頭函數等價定義 () => { console.log('hello'); }
箭頭函數在定義回調函數中使用的很是多,可是在 Vue 中的 watch 對象的回調函數中就不能使用回調函數,先看下面的例子:瀏覽器
代碼有一點長,簡單說明一下就不用看全部的代碼了,下面代碼實現的是實現監視數據 a 和 b 的變化,當其中一個改變時執行相應的回調函數求a與b的和,重點在 23-30 行。app
下面的代碼中 watch 中回調函數是普通的函數,咱們知道 對於普通函數,函數中的this指向函數運行時所在的對象。函數
因此,當咱們在瀏覽器中改變a的值時(例如在瀏覽器的控制檯輸入 vm.a = 10),代碼 23 行打印出來的是一個 Vue 對象(即代碼 14行新建立出來的vm實例),由於此時 代碼 22 行的 function 函數運行在 vm 對象中,此時頁面會發生變化,由原來的 3 變爲 12.學習
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Vue中的watch</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="app"> {{sum}} </div> <script> var vm = new Vue({ el: "#app", data: { a: 1, b: 2, sum: 3 }, watch: { a: function() { console.log(this); this.sum = this.a + this.b; }, b: function() { this.sum = this.a + this.b; } } }) </script> </body> </html>
咱們再來看一下用箭頭函數當作 watch 的回調函數的狀況,把代碼21-29行換成以下的代碼便可:this
watch: { a: () => { console.log(this); this.sum = this.a + this.b; }, b: () => { this.sum = this.a + this.b; } }
當咱們這時候再在瀏覽器的控制檯改變 a 的值時(好比 在控制檯輸入 vm.a = 10),會發現打印出來的是 window 對象,因此頁面的內容也不會發生變化。spa
JS 代碼分爲 預解析階段和執行階段,在預解析階段遇到函數聲明會提早進行預解析,此時下面代碼中的箭頭函數會在全局定義,由於 var vm = new Vue({...})
這句代碼在預解析階段尚未被執行。當到了執行階段而且在控制檯改變 a 的值後,watch 中的下面代碼中的箭頭函數開始執行,此時的運行環境確實是新建立的 vm 對象。可是對於箭頭函數來講,**箭頭函數中的 this 指向的是定義時的對象而不是函數運行時所在的對象,**這一點與普通函數有很大的區別。.net
a: () => { console.log(this); this.sum = this.a + this.b; }
若是對於 this 的指向問題若是還不是很清楚能夠參考下面的兩篇博客:
完
歡迎指正