當data中某個屬性的值發生變化須要執行一些其它操做時,可使用watch去監聽這個屬性,當屬性值發生變化時,執行回調函數,處理相應的操做。vue
當監聽的屬性不是object對象時。異步
data: function() { return { num: 0, }; } watch: { num: function(newV, oldV) { console.log('num由'+oldV+'變成了'+newV); }, }
當監聽的是一個object對象時,object中屬性值發生變化時不會觸發回調函數,由於object指向的地址沒有發生變化,因此監聽對象發生變化時有如下三種方法。函數
監聽的user對象。性能
data: function() { return { user: { name: 'zhang san', age: 23, }, }; }
方法1:當給user對象從新賦值時,能夠直接監聽user對象。this
watch: { user: function(newV, oldV) { console.log('user由'+oldV+'變成了'+newV); }, }
方法2:使用deep參數。code
使用deep須要使用watch的完整形式:handler是監聽回調函數,deep: true指定了不單單監聽user的變化,也監聽其內部屬性的變化,因此當user.name或user.age變化時都能觸發handler回調。對象
watch: { counter: { // user或者user的屬性發生變化時,都會觸發handler函數。 handler: function(newV) { console.log(newV); }, deep: true, } }
比較方法1和方法2的優缺點rxjs
使用deep參數會爲數據每一層都添加監聽,當層級較深時比較耗費性能。因此通常來講使用從新賦值的方式是較優的方案,但若是隻是想監聽內部嵌套的某個屬性的數據的話,從新賦值就比較重了,下面介紹監聽對象中某個屬性的方法。
方法3:監聽object對象中的某個屬性。事件
watch: { user.name: function(newV, oldV) { console.log('name屬性由'+oldV+'變成了'+newV); }, user.age: function(newV, oldV) { console.log('age屬性由'+oldV+'變成了'+newV); } }
方法一: angular中監聽數據變化可使用鉤子函數ngDoCheck來監聽。回調函數
export class TestComponent implements DoCheck { public name = 'zhangsan'; public oldName: string; constructor() { this.oldName = this.name; } ngDoCheck() { if (this.name !== this.oldName) { console.log('name發生了變化!'); } } }
此鉤子函數在發生髒值檢測時就會被調用,觸發髒值檢測的條件有Dom事件、異步請求、Location變動事件等等,所以會有大量狀況觸發此鉤子函數,不多的調用是因爲數據修改而觸發,所以可能產生性能問題。
方法二:angular棄用了angular1中的數據監聽$watch方法,但官方引入了rxJS來解決相似數據監聽的需求。
場景:在commonService中定義初始化語言'en',當切換語言時,在組件中監聽並執行對應操做。
在commonService中
import { BehaviorSubject } from 'rxjs'; export class CommonService { // 定義language,設置初始語言'en'。 public language = new BehaviorSubject<string>('en'); constructor() { } changeLanguage(lang) { // 點擊切換語言時,調用language對象的next方法。 this.language.next(lang); } }
在其它組件中監聽language的變化,來執行相應操做。
在TestComponent 中
export class TestComponent { public lang: string; constructor(public commonService: CommonService) { // 調用next()方法後,此處訂閱得到變化後的值。 this.commonService.language.subscribe((lang) => { this.lang = lang; }); } }