前言
金三银四,到了面试的白热化状态了,不知道各位友友都面的如何了。最近发现面试经常问VUE中的computed
和watch
的区别,正好写一篇文章来拿下这道小题。
computed
computed
是vue中的计算属性,其可以组合现有的数据生成新的数据,且自动追踪依赖并缓存结构。
依赖机制
- 依赖追踪
Vue 会自动追踪 computed
属性中使用的响应式数据,并在计算属性访问时建立起依赖关系。这意味着,当计算属性的值被访问时,Vue 会知道这个计算属性依赖哪些响应式数据。Vue 会将这些依赖的数据与计算属性绑定在一起。
- 缓存机制
计算属性的一个关键特点是它具有缓存机制。Vue 会记住计算属性上次的计算结果以及它所依赖的数据。当这些依赖的数据发生变化时,计算属性会重新计算;如果没有发生变化,则 Vue 会直接返回上次计算的缓存值。
这种机制避免了不必要的计算,提高了性能,尤其是在计算过程较为复杂时。
- 计算属性依赖的更新
当计算属性依赖的数据发生变化时,Vue 会标记这些计算属性为"脏"(dirty)。下次访问时,Vue 会重新计算该计算属性并更新缓存。如果依赖的数据没有变化,Vue 就会直接返回缓存值。
computed的两种写法
选项式写法 在选项式写法中,computed
属性是一个对象,其中每个属性都是一个函数(getter),并且你可以通过传递 set
方法来定义一个setter,用于修改计算属性的值。
比如:
xml
<template>
<div>
姓:<input v-model="Name1" >
</div>
<div>
名:<input v-model="Name2" >
</div>
<div>
姓名: {{fullName}}
<button @click="change">修改</button>
</div>
</template>
<script setup>
import { ref,computed } from 'vue'
let Name1 = ref('zhang')
let Name2 = ref('san')
const fullName=computed({
get(){
return Name1.value +"-"+ Name2.value;
},
set(value){
let names = value.split('-')
Name1.value = names[0]
Name2.value = names[1]
}
})
function change(){
fullName.value = '李-四'
}
</script>
<style scoped>
</style>
在这个例子中,fullName
计算属性有一个 get
方法和一个 set
方法。get
方法是用来获取计算值的,而 set
方法则用于设置计算属性的值。在 set
方法中,我们将输入的值分割成 Name1
和 Name2
,从而实现修改计算属性的值。
函数式写法 在函数式写法中,
computed
属性直接是一个函数,这种写法更加简洁,它只支持一个grtter函数,不允许修改值。
js
const fullName=computed(=>{
Name1.value +"-"+ Name2.value;
})
watch
在 Vue 中,watch
是一个强大的工具,用于观察数据变化并在数据变化时执行自定义操作。
watch的基本概念
watch
是 Vue 实例的一个选项,它可以监听一个或多个数据源的变化,并在变化发生时执行相应的回调函数。
watch
的基本语法
javascript
new Vue({
data() {
return {
searchQuery: '',
results: []
};
},
watch: {
// 监听 searchQuery 的变化
searchQuery(newValue, oldValue) {
// 当 searchQuery 改变时执行的操作
console.log(`searchQuery changed from "${oldValue}" to "${newValue}"`);
this.fetchResults(newValue);
}
},
methods: {
fetchResults(query) {
// 模拟 API 请求
setTimeout(() => {
this.results = [`Result for "${query}"`];
}, 500);
}
}
});
案例: 比如我们在网站中进行商品搜索时,可以用watch来监听数据变化,防抖处理避免频繁请求。
ini
import { ref, watch, onMounted, computed } from 'vue';
import axios from 'axios';
import { debounce } from 'lodash-es';
const searchQuery = ref('');
const priceRange = ref([0, 10000]);
const debouncedFetchProducts = debounce(fetchProducts, 500);
watch([searchQuery, priceRange], () => {
debouncedFetchProducts();
}, { deep: true });
这里watch同时监视 searchQuery (搜索关键词)和 priceRange (价格范围)这两个响应式数据 ,当这两个值中的任何一个发生变化时,都会触发回调函数。
watch
vs computed
computed
主要用于计算派生数据,且会根据依赖的响应式数据自动缓存,避免重复计算。watch
则更多用于执行副作用操作,如异步请求、操作外部 API 或改变其他数据等,它不缓存数据,每次监听到变化都会执行回调。
总结:
-
watch
主要用于执行副作用操作,它监听数据的变化,并在变化时触发回调函数。 -
可以通过
deep
来深度监听对象、数组的变化,通过immediate
来使watch
立即执行一次。 -
watch
的回调接收两个参数:newValue
和oldValue
,用于比较数据前后的变化。 -
它在处理异步操作时特别有用,比如发起 API 请求等。