Vue中的計算屬性和偵聽器比較

GeekQiaQia發表於2019-04-08

Vue 中合理應用計算屬性computed和偵聽器watch;

什麼是計算屬性:

計算屬性可以理解為:可以用來寫一些邏輯的屬性;
複製程式碼

作用:

1.通常用來減少模板中計算邏輯;
2.幫助我們做一些資料的快取;當我們的依賴資料沒有變化的時候,不會執行邏輯程式碼;當邏輯計算的比較複雜的時候,可以幫助我們提供效能;因為它只會在依賴資料變化的時候才會計算;
3.依賴固定的資料型別(響應式資料型別)
複製程式碼

引用唐老師的示例程式碼: 通過斷點程式碼,理解計算屬性computed:

在以下computed.vue 中;在data中初始化message;通過點選button,執行this.$forceUpdate(),強制重新整理;我們可以發現:

在計算屬性reversedMessage1中邏輯程式碼的log;並咩有更新;reversedMessage2 中邏輯程式碼的log 一直有列印;這就是通過computed 屬性的優點;

<template>
  <div>
<p>Reversed message1: "{{ reversedMessage1 }}"</p>
<p>Reversed message2: "{{ reversedMessage2() }}"</p>
<p>{{ now }}</p>
<button @click="() => $forceUpdate()">forceUpdate</button>
<br />
<input v-model="message" />
  </div>
</template>
<script>
export default {
  data() {
return {
  message: "hello vue"
};
  },
  computed: {
// 計算屬性的 getter
reversedMessage1: function() {
  console.log("執行reversedMessage1");
  return this.message
.split("")
.reverse()
.join("");
},
now: function() {
  return Date.now();
}
  },
  methods: {
reversedMessage2: function() {
  console.log("執行reversedMessage2");
  return this.message
.split("")
.reverse()
.join("");
}
  }
};
</script>
複製程式碼

什麼是偵聽器watch:

**偵聽器**:可以去監聽任何資料;當資料變化的時候,去執行一些邏輯程式碼;
在watch中可以執行任何程式碼邏輯,如函式節流、ajax非同步獲取資料;甚至操作Dom;
複製程式碼

偵聽器的作用:更加靈活,通用;

引用唐老師的程式碼示例: 通過程式碼理解偵聽器:

在watch.vue程式碼示例中,

  1. 在{{}}模板中通過$data 引用data中的所有資料;

  2. 通過button 來改變a的值;

  3. 在watch中,通過監聽多層巢狀資料,當a發生變化的時候,執行對應邏輯程式碼;

  4. 在e 中,執行深度監聽,deep:true;當e:中的任何資料發生改變的時候,不論是f 還是g 發生改變,都將執行e的handler 函式;

計算屬性computed VS 偵聽器watch;

計算屬性computed 能夠做的,watch 都可以做,反之不行; 能用computed做的事情,儘量使用computed;

通過程式碼理解兩者:

computedFullName.vue中;通過計算屬性fullName;只需要一段邏輯程式碼,便可以完成Fullname的監聽;

<template>
  <div>
{{ fullName }}

<div>firstName: <input v-model="firstName" /></div>
<div>lastName: <input v-model="lastName" /></div>
  </div>
</template>
<script>
export default {
  data: function() {
return {
  firstName: "Foo",
  lastName: "Bar"
};
  },
  computed: {
fullName: function() {
  return this.firstName + " " + this.lastName;
}
  },
  watch: {
fullName: function(val, oldVal) {
  console.log("new: %s, old: %s", val, oldVal);
}
  }
};
</script>
複製程式碼

watchFullName.vue 中;顯示fullName的改變需要;同時監聽firstName 和lastName;分別執行兩段邏輯程式碼;

<template>
  <div>
{{ fullName }}

<div>firstName: <input v-model="firstName" /></div>
<div>lastName: <input v-model="lastName" /></div>
  </div>
</template>
<script>
export default {
  data: function() {
return {
  firstName: "Foo",
  lastName: "Bar",
  fullName: "Foo Bar"
};
  },
  watch: {
firstName: function(val) {
  this.fullName = val + " " + this.lastName;
},
lastName: function(val) {
  this.fullName = this.firstName + " " + val;
}
  }
};
</script>
複製程式碼

在這種情況下,程式碼量上來講,通過computed 計算屬性更加簡潔;computed 可以做的通過watch屬性也可以進行實現;

**擴充套件:**對以上watchFullName.vue 進行防抖改造,當使用者輸入超過500毫秒後,才進行更新fullname;

**分析:**通過程式碼分析可以看出,防抖策略:

就是通過 clearTimeout(timer);let timer=setTimeout(()=>{}); 當使用者一直輸入新的資料的時候,清除當前定時器,如果500ms內,監聽的依賴資料沒有新的資料更新, 在執行setTimeout(()=>{})的回撥函式;

<template>
  <div>
{{ fullName }}

<div>firstName: <input v-model="firstName" /></div>
<div>lastName: <input v-model="lastName" /></div>
  </div>
</template>
<script>
export default {
  data: function() {
return {
  firstName: "Foo",
  lastName: "Bar",
  fullName: "Foo Bar"
};
  }, 
  watch: {
firstName: function(val) {
  clearTimeout(this.firstTimeout);
  this.firstTimeout = setTimeout(() => {
this.fullName = val + " " + this.lastName;
  }, 500);
},
lastName: function(val) {
  clearTimeout(this.lastTimeout);
  this.lastTimeout = setTimeout(() => {
this.fullName = this.firstName + " " + val;
  }, 500);
}
  }
};
</script>
複製程式碼

相關文章