computed() 与 watch()
使用 computed() 延迟派生值,使用 watch() 和 watchEffect() 响应状态变化,并控制刷新时机。
computed() 与 watch() 是 CoddyKit 上的免费 Frontend Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Frontend Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Frontend Academy 课程共包含 4 节课。
Composition API 中的 computed()
computed(fn) 会创建一个只读的响应式 ref,其值由其他响应式源派生而来。它会被缓存——只有依赖项发生变化时,getter 才会运行。
<script setup>
import { ref, computed } from 'vue';
const items = ref([{ price: 10 }, { price: 20 }, { price: 30 }]);
const tax = ref(0.1);
const subtotal = computed(() => items.value.reduce((s, i) => s + i.price, 0));
const total = computed(() => subtotal.value * (1 + tax.value));
</script>可写的 computed()
传入包含 get 和 set 的对象即可创建可写的 computed。setter 负责处理更新,通常会将变化同步回源 ref。
const firstName = ref('Alice');
const lastName = ref('Smith');
const fullName = computed({
get: () => `${firstName.value} ${lastName.value}`,
set: (val: string) => {
[firstName.value, lastName.value] = val.split(' ');
}
});
fullName.value = 'Bob Jones'; // sets both refswatch() 基础
watch(source, callback) 会在源发生变化时运行回调。回调会接收新值和旧值。
import { ref, watch } from 'vue';
const query = ref('');
watch(query, (newVal, oldVal) => {
console.log(`Changed from '${oldVal}' to '${newVal}'`);
searchAPI(newVal);
});侦听 ref 与 reactive
可以直接侦听 ref。要侦听响应式属性,请使用 getter 函数 () => state.prop。
const count = ref(0);
watch(count, val => console.log('count:', val));
const state = reactive({ count: 0, name: '' });
watch(() => state.count, val => console.log('state.count:', val));深度侦听
传入 { deep: true },即可侦听对象 ref 中的嵌套变化。
const user = ref({ name: 'Alice', address: { city: 'NY' } });
watch(user, (newUser) => {
console.log('user changed:', newUser);
}, { deep: true });立即侦听
传入 { immediate: true },即可在设置时立即运行回调,而无需等待任何变化。当您希望使用初始值执行副作用时,这非常有用。
watch(userId, async (id) => {
user.value = await fetchUser(id);
}, { immediate: true }); // runs once on setup, then on changewatchEffect()
watchEffect(fn) 会立即运行回调,并在其中使用的任何响应式依赖发生变化时重新运行。无需显式指定源。
import { watchEffect } from 'vue';
watchEffect(() => {
// runs immediately and whenever query or page changes:
fetchResults(query.value, page.value);
});watchEffect 与 watch
watchEffect:立即运行,自动跟踪依赖项,无法访问旧值。watch:显式指定源,默认延迟运行,可以访问旧值和新值。当您需要声明式地处理副作用时,请使用 watchEffect;当您需要控制运行时机或频率时,请使用 watch。
停止侦听器
watch 和 watchEffect 都会返回一个停止函数。调用它即可停止侦听。在