相同点:
响应性: 都是Vue响应式系统的一部分, 都会自动追踪依赖的响应式数据, 并在这些数据变化时重新执行.
计算属性 (Computed Properties ):
特性:
1. 缓存: 计算属性会缓存结果, 只有当依赖项发生变化时, 计算属性才会重新计算.
2. 同步: 计算属性通常是同步操作, 不适合执行异步或副作用.
3. 返回值: 计算属性会返回一个值, 这个值会被缓存, 知道依赖的响应式数据变.
使用场景:
1.数据聚合时
import { ref, computed } from 'vue';
export default {
setup() {
const firstName = ref('John');
const lastName = ref('Doe');
const fullName = computed(() => `${firstName.value} ${lastName.value}`);
return { firstName, lastName, fullName };
}
};
2.基于现有数据生成新数据时.
export default {
setup() {
const organizationList = [........]
const res = computed(() => {
return organizationList.filter((item) => item.minLevel > 0 && item.level > 0 );
});
return { res };
}
};
3.复杂计算时
import { ref, computed } from 'vue';
export default {
setup() {
const items = ref([{ price: 10 }, { price: 20 }, { price: 30 }]);
const totalPrice = computed(() => {
return items.value.reduce((sum, item) => sum + item.price, 0);
});
return { items, totalPrice };
}
};
4.多重条件判断时.
import { ref, computed } from 'vue';
export default {
setup() {
const innerDisabled = true;
const disabled = true;
const ok = true;
const isDisabled = computed(() => innerDisabled && disabled && ok );
return { isDisabled };
}
};
5.数组过滤与排序
// 在处理列表时,计算属性可以用来对列表进行过滤、排序或其他数组操作,而不会影响原始数据。
import { ref, computed } from 'vue';
export default {
setup() {
const users = ref([
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 30 },
{ name: 'Carol', age: 22 }
]);
const sortedUsers = computed(() => {
return users.value.slice().sort((a, b) => a.age - b.age);
});
return { users, sortedUsers };
}
};
观察者 ( Watchers ):
特性:
1. 无缓存: watch不会缓存数据, 它会在每次依赖的响应式数据变化时执行.
2. 有新旧值.
3. 更多控制: watch提供了更多的控制, 如立即执行, 深度观察.
4. 通常用来执行副作用: 如异步请求, 操作DOM等
使用场景:
1.watch 可以同时监听多个响应式数据源,并在它们变化时执行回调。
2.当响应式数据变化需要执行异步操作,如从服务器获取数据,watch 可以在数据变化后触发这些操作,并处理异步操作的结果。
3.可以在watch的回调函数中执行任何操作,而不仅仅是计算一个值。
4.在使用前端路由时,watch 可以用来监听路由变化,执行如权限验证、数据预加载、状态重置等操作。
副作用跟踪 ( watchEffect ):
特性:
1.自动收集依赖: watchEffect 会自动追踪执行过程中用到的响应式状态, 并在状态发生变化时重新执行.
2. 立即执行: watchEffect会立即执行一次.
3. 不返回值: watchEffect 没有返回值, 它用于执行副作用.
使用场景:
1.自动追踪响应式状态的变化.
// 只要watchEffect使用了某个属性, 当这个属性发生变化后,就会执行当前watchEffect函数
import { ref, watchEffect } from 'vue';
export default {
setup() {
const count = ref(0);
watchEffect(() => {
console.log(`count is now: ${count.value}`);
});
}
};
2.与计算属性结合使用.
// 当你有一个计算属性,并且想在它的值发生变化时执行某些动作时,你可以使用watchEffect来自动追踪这个计算属性的依赖。
import { ref, computed, watchEffect } from 'vue';
export default {
setup() {
const firstName = ref('Jane');
const lastName = ref('Smith');
const fullName = computed(() => `${firstName.value} ${lastName.value}`);
watchEffect(() => {
document.title = fullName.value;
});
return { firstName, lastName };
}
};
3.数据获取和异步操作
// watchEffect可以用于在依赖的响应式状态变化时执行异步操作,如数据获取。
import { ref, watchEffect } from 'vue';
import axios from 'axios';
export default {
setup() {
const userId = ref(1);
const user = ref(null);
watchEffect(async () => {
const response = await axios.get(`/api/users/${userId.value}`);
user.value = response.data;
});
return { userId, user };
}
};
4.监听路有变化
// 在Vue应用中,你可能需要在路由变化时执行副作用,watchEffect可以用来追踪路由状态的变化。
import { watchEffect } from 'vue';
import { useRoute } from 'vue-router';
export default {
setup() {
const route = useRoute();
watchEffect(() => {
// 假设我们想在路由参数变化时执行一些操作
console.log(`Current route id is: ${route.params.id}`);
});
}
};
- 相同点:计算属性、watch 和 watchEffect 都是基于 Vue 的响应式系统建立的,都用于追踪响应式状态的变化。
- 不同点:
- 计算属性提供缓存和惰性求值,主要用于同步计算值。
- watch 提供更细粒度的控制,允许访问旧值和新值,适用于数据变化响应时执行更复杂的操作。
- watchEffect 不需要指定侦听的具体数据,会自动收集依赖,并在依赖变化时执行,适用于副作用的自动管理。