一、Vue3 计算属性(computed)
在 Vue 3 中,计算属性(Computed Properties)是一种强大的功能,它允许你声明一个依赖于其他响应式数据属性的属性,并且这个属性的值会根据其依赖的数据的变化而自动更新。计算属性是基于它们的依赖关系进行缓存的,只有在它的相关依赖发生改变时才会重新求值。
下面是如何在 Vue 3 中使用计算属性的一个简单示例:
<template>
<div>
<p>原始值:{
{ message }}</p>
<p>计算后的值:{
{ reversedMessage }}</p>
<button @click="message = 'Hello World!'">修改原始值</button>
</div>
</template>
<script>
import {
ref, computed } from 'vue';
export default {
setup() {
const message = ref('Hello Vue3');
const reversedMessage = computed(() => {
return message.value.split('').reverse().join('');
});
return {
message,
reversedMessage
};
}
}
</script>
在这个例子中,我们有一个响应式引用 message
,它包含一个字符串。我们还定义了一个计算属性 reversedMessage
,它返回 message
的逆序字符串。当 message
的值发生变化时,reversedMessage
的值也会自动更新。
在 Vue 3 的 Composition API 中,我们使用 setup
函数来定义组件的逻辑。在这个函数中,我们可以使用 ref
来创建响应式引用,使用 computed
来创建计算属性。
计算属性在处理复杂逻辑或计算时非常有用,因为它们可以缓存结果,只有在依赖的数据发生变化时才会重新计算,这有助于提高性能。
二、Vue3 计算属性的getter与setter
在 Vue 3 中,计算属性不仅仅是一个简单的计算结果的缓存,它们还允许你定义一个 setter 函数,该函数会在你尝试修改计算属性的值时触发。这为你提供了一种方式来观察或拦截对计算属性的更改。
下面是一个使用 getter 和 setter 的计算属性示例:
<template>
<div>
<p>计算属性的值:{
{ computedValue }}</p>
<button @click="incrementComputedValue">增加计算属性的值</button>
</div>
</template>
<script>
import {
ref, computed } from 'vue';
export default {
setup() {
const baseValue = ref(1);
const computedValue = computed({
get() {
return baseValue.value * 2; // Getter
},
set(newValue) {
baseValue.value = newValue / 2; // Setter
}
});
function incrementComputedValue() {
// 直接修改计算属性的值会触发 setter
computedValue.value += 1;
}
return {
computedValue,
incrementComputedValue
};
}
}
</script>
在这个例子中,computedValue
是一个计算属性,它有一个 getter 和一个 setter。getter 函数返回 baseValue
的两倍,而 setter 函数接受一个新的值,并将其除以 2 来更新 baseValue
。
当你尝试通过 computedValue.value = someValue
修改计算属性的值时,setter 会被调用。在上面的示例中,当你点击按钮时,incrementComputedValue
函数会增加 computedValue
的值,这会触发 setter,导致 baseValue
被适当地更新。
需要注意的是,计算属性的 setter 并不常见,因为计算属性通常用于基于其他响应式属性的只读值。如果你需要一个可以设置的值,通常最好使用普通的响应式引用(ref
)或响应式对象(reactive
)。然而,在某些特殊情况下,你可能需要计算属性的 setter 来执行一些自定义逻辑,例如在值改变时发送通知或执行副作用。
三、Vue3 监听属性(watch)
在 Vue 3 中,如果你想要监听某个属性的变化并在变化时执行某些操作,你可以使用 watch
函数或 watchEffect
函数。这两个函数都在 setup
函数内部可用,是 Vue 3 Composition API 的一部分。
使用 watch
函数
watch
函数允许你监听一个或多个响应式引用或计算属性的变化,并在它们变化时执行一个回调函数。
<template>
<div>
<p>被监听的属性值:{
{ count }}</p>
<button @click="incrementCount">增加</button>
</div>
</template>
<script>
import {
ref, watch } from 'vue';
export default {
setup() {
const count = ref(0);
// 使用 watch 监听 count 的变化
watch(count, (newValue, oldValue) => {
console.log(`Count changed from ${
oldValue} to ${
newValue}`);
// 在这里执行你想要的任何操作
});
function incrementCount() {
count.value++;
}
return {
count,
incrementCount
};
}
}
</script>
在这个例子中,我们创建了一个响应式引用 count
并使用 watch
来监听它的变化。每当 count
的值改变时,回调函数都会被调用,并打印出旧值和新值。
使用 watchEffect
函数
watchEffect
函数则会自动收集依赖,并在依赖发生变化时重新运行一个给定的函数。这个函数不需要显式地指定依赖项。
<template>
<div>
<p>被监听的属性值:{
{ count }}</p>
<button @click="incrementCount">增加</button>
</div>
</template>
<script>
import {
ref, watchEffect } from 'vue';
export default {
setup() {
const count = ref(0);
// 使用 watchEffect 监听依赖的变化
watchEffect(() => {
console.log(`Count is now ${
count.value}`);
// 在这里执行你想要的任何操作
});
function incrementCount() {
count.value++;
}
return {
count,
incrementCount
};
}
}
</script>
在这个例子中,watchEffect
会自动检测 count.value
的变化,并在每次变化时运行提供的函数。
对比 watch
和 watchEffect
watch
需要你显式地指定要监听的响应式引用或计算属性,并且你可以访问变化前后的值。watchEffect
则会自动收集其函数内部的依赖,并在这些依赖变化时重新运行该函数。它不需要你指定依赖项,但你不能直接访问变化前后的值(不过你可以通过闭包或其他方式来间接访问)。
选择使用哪一个取决于你的具体需求和你想要如何组织你的代码。如果你需要更细粒度的控制或需要访问变化前后的值,那么 watch
可能是更好的选择。如果你想要更简洁的语法并且不关心具体的依赖项,那么 watchEffect
可能会更适合你。
四、Vue3 computed与watch比较
在 Vue 3 中,computed
和 watch
各自有不同的用途,并且服务于不同的目的。以下是它们的比较:
computed(计算属性)
用途:用于声明一个依赖于其他响应式数据属性的属性,并且这个属性的值会根据其依赖的数据的变化而自动更新。计算属性是基于它们的依赖关系进行缓存的,只有在它的相关依赖发生改变时才会重新求值。
特点:
- 响应式:计算属性是响应式的,当依赖的数据变化时,计算属性会自动更新。
- 缓存:计算属性会缓存其结果,只有当依赖的属性发生变化时才会重新计算。
- 只读:计算属性默认是只读的,你不能直接修改它们的值。尝试这样做会导致警告或错误。
- Getter 和 Setter:你可以为计算属性提供 getter 和 setter 函数,以控制属性的读取和写入行为。
适用场景:当你需要根据其他响应式数据动态计算出一个新值时,使用计算属性。
watch(监听属性)
用途:用于观察一个或多个响应式数据属性的变化,并在它们变化时执行一个回调函数。
特点:
- 观察变化:
watch
用于观察数据属性的变化,并在数据变化时触发回调。 - 灵活性:你可以选择监听特定的属性,并且可以访问变化前后的值。
- 自动或手动:
watch
可以是自动的(通过watchEffect
),也可以是手动的(通过watch
),取决于你是否想要显式指定依赖。 - 执行回调:当监听的数据变化时,
watch
会执行提供的回调函数。
- 观察变化:
适用场景:当你需要在数据变化时执行某些副作用操作(如发送请求、更新DOM等)时,使用
watch
。
总结
- computed 适用于根据其他响应式数据动态计算出一个新值,并且这个值需要被频繁读取的场景。
- watch 适用于在数据变化时需要执行某些操作(如副作用)的场景,特别是当你需要访问变化前后的值或需要执行异步操作时。