Vue计算与监听属性

computed简介

computed 是 Vue.js 中的一个重要概念,它是一种用于声明计算属性的方式。计算属性是一种根据组件的状态(响应式数据)计算派生值的属性,这些属性的值是基于其他属性计算得来的。计算属性具有以下特点:

  1. 缓存机制:计算属性具有缓存机制,只有依赖的响应式数据发生变化时,才会重新计算。这意味着计算属性的值在依赖数据不变的情况下会被缓存,不会重复计算,以提高性能。
  2. 声明方式:计算属性通过在组件的 computed 选项中声明,使用对象字面量来定义计算属性的名称和计算逻辑。
  3. 与普通属性一样访问:在模板中,可以像访问普通属性一样使用计算属性,而不需要在模板中编写复杂的计算逻辑。
  4. 响应式:计算属性的值也是响应式的,它会自动跟踪依赖数据的变化,并在必要时重新计算。

下面是一个示例,演示了如何使用 computed

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<template>
<div>
<p>原始值:{{ message }}</p>
<p>反转后的值:{{ reversedMessage }}</p>
</div>
</template>

<script>
export default {
data() {
return {
message: 'Hello Vue'
};
},
computed: {
reversedMessage() {
return this.message.split('').reverse().join('');
}
}
};
</script>

在上面的示例中,我们定义了一个计算属性 reversedMessage,它根据 message 的值计算出反转后的字符串。在模板中,可以直接使用 {{ reversedMessage }} 来显示反转后的值,而不需要在模板中编写详细的计算逻辑。此外,reversedMessage 具有缓存机制,只有 message 发生变化时才会重新计算。

methods和computed区别

在 Vue.js 中,computedmethods 都用于定义组件内部的方法,但它们有一些关键的区别:

  1. 计算属性 (computed):

    • 计算属性是基于组件的响应式数据计算而来的属性。
    • 计算属性具有缓存机制,只有依赖的响应式数据发生变化时,才会重新计算。如果多次访问同一个计算属性且没有发生依赖数据变化,计算属性会返回之前缓存的计算结果,而不会重复计算。
    • 计算属性适用于根据其他属性计算出一个新的值的情况,通常用于模板中。
1
2
3
4
5
computed: {
fullName() {
return this.firstName + ' ' + this.lastName;
}
}
  1. 方法 (methods):

    • 方法是普通的 JavaScript 函数,它们可以执行任何操作,并且没有缓存机制。
    • 每次调用方法时,都会重新执行方法内的代码,不管依赖的数据是否发生变化。
    • 方法适用于需要执行一些逻辑操作或者需要传递参数的情况,通常用于事件处理或其他响应式操作之外的场景。
1
2
3
4
5
methods: {
greet() {
alert('Hello, Vue.js!');
}
}

总结一下,选择使用 computed 还是 methods 取决于你的需求:

  • 如果您需要基于响应式数据计算出一个新的属性值,并且希望具有缓存机制以避免重复计算,那么使用 computed 更合适。
  • 如果您需要执行一些逻辑操作,不依赖于响应式数据的变化,或者需要传递参数,那么使用 methods 更合适。
    在实际开发中,通常会根据需求来选择使用哪种方式,以提高代码的可读性和性能。

getter与setter

getter

在 Vue.js 的 computed 属性中,默认情况下,getter 是一个用于计算计算属性值的函数。计算属性的 getter 函数负责返回计算后的值,这个值会根据计算属性所依赖的响应式数据的变化而动态更新。

例如,以下是一个简单的计算属性示例:

1
2
3
4
5
computed: {
fullName() {
return this.firstName + ' ' + this.lastName;
}
}

在这个示例中,fullName 是一个计算属性,它的 getter 函数负责计算和返回 firstNamelastName 组合而成的全名。每当 firstNamelastName 发生变化时,fullName 的 getter 函数会被触发,重新计算并返回全名。

默认情况下,computed 属性中的 getter 函数是一个匿名函数,它负责计算属性的值。这个匿名函数可以包含任何合法的 JavaScript 代码,用于计算派生值。getter 函数不接受参数,但可以访问组件实例的属性和其他计算属性。

需要注意的是,计算属性的 getter 函数只负责计算属性的值,而不应该用于修改数据。如果需要在计算属性中进行设置或修改,可以使用计算属性的 setter 函数,但默认情况下,大多数计算属性只包含 getter 函数。

setter

在 Vue.js 的计算属性 (computed) 中,可以使用 setter 函数来定义计算属性的值,并且允许您在计算属性被设置时执行一些自定义逻辑。Setter 函数的主要用途是在计算属性的值发生变化时触发副作用或执行一些操作。

计算属性的 setter 函数的语法如下:

1
2
3
4
5
6
7
8
9
10
11
computed: {
propertyName: {
get() {
// 计算并返回计算属性的值
},
set(value) {
// 当计算属性的值被设置时执行的逻辑
// value 参数是设置的新值
}
}
}

以下是一个具体的示例,演示了如何在计算属性中使用 setter 函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue 3 Computed Property Example with Setter</title>
<script src="https://unpkg.com/vue@3.2.36/dist/vue.global.prod.js"></script>
</head>
<body>
<div id="app">
<h1>用户信息</h1>
<p>姓: <input v-model="firstName"></p>
<p>名: <input v-model="lastName"></p>
<p>全名: {{ fullName }}</p>
</div>

<script>
const app = Vue.createApp({
data() {
return {
firstName: '',
lastName: ''
};
},
computed: {
fullName: {
get() {
return this.firstName + ' ' + this.lastName;
},
set(value) {
const parts = value.split(' ');
this.firstName = parts[0];
this.lastName = parts[1];
}
}
}
});

app.mount('#app');
</script>
</body>
</html>

在这个示例中,我们使用了计算属性 fullName 的 setter 函数,以便在用户输入全名时自动将其拆分为姓和名,并更新 firstNamelastName。这是 setter 函数的一个常见用法,用于从视图修改响应式数据。当用户在输入框中输入全名时,计算属性的 setter 函数将被触发,从而更新了 firstNamelastName,并且反映在视图中。

watch简介

在 Vue.js 中,watch 属性用于监视数据的变化并执行相应的操作。您可以使用 watch 来监听一个或多个数据属性的变化,一旦这些属性发生变化,就可以触发自定义的回调函数执行特定的操作。

watch 属性的基本结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
watch: {
// 监听的数据属性
propertyName: {
handler(newValue, oldValue) {
// 在属性变化时执行的回调函数
// newValue 是新的属性值
// oldValue 是旧的属性值
},
deep: true, // 可选:深度监听对象或数组的变化
immediate: true, // 可选:在组件初始化时立即执行回调函数
},
// 可以监听多个属性
anotherProperty: {
handler(newValue, oldValue) {
// 回调函数逻辑
},
},
}

下面是关于 watch 属性的一些关键概念和用法:

  1. 属性名称:在 watch 对象中,您指定要监听的数据属性的名称,例如 propertyNameanotherProperty。当这些属性的值发生变化时,Vue.js 将执行相应的回调函数。

  2. handler 回调函数handler 是一个回调函数,它会在属性值发生变化时被调用。该函数接收两个参数:newValueoldValue,分别表示属性的新值和旧值。您可以在 handler 函数中执行任何自定义逻辑,例如处理新值和旧值之间的差异。

  3. deep 选项deep 选项是一个布尔值,默认为 false。如果将 deep 设置为 true,Vue.js 将深度递归地监听对象或数组的变化。这意味着当对象内部的属性或数组元素发生变化时,也会触发 watch 回调函数。

  4. immediate 选项immediate 选项是一个布尔值,默认为 false。如果将 immediate 设置为 true,Vue.js 在组件初始化时将立即执行 watch 回调函数,而不需要等待属性的变化。这对于初始化时执行一次回调函数很有用。

以下是一个示例,演示如何使用 watch 属性来监听数据属性的变化:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue Watch 示例</title>
<script src="https://unpkg.com/vue@3.2.36/dist/vue.global.prod.js"></script>
</head>
<body>
<div id="app">
<h1>{{ message }}</h1>
<p>计数: {{ count }}</p>
<button @click="changeMessage">改变消息</button>
<button @click="increaseCount">增加计数</button>
</div>

<script>
const app = Vue.createApp({
data() {
return {
message: 'Hello, Vue!',
count: 0,
};
},
watch: {
message(newValue, oldValue) {
console.log(`消息从 "${oldValue}" 变为 "${newValue}"`);
},
count(newValue, oldValue) {
console.log(`计数从 ${oldValue} 变为 ${newValue}`);
},
},
methods: {
changeMessage() {
this.message = 'Vue 是很棒的!';
},
increaseCount() {
this.count++;
},
},
});

app.mount('#app');
</script>
</body>
</html>

在这个示例中,我们定义了一个 watch 对象,分别监听了 messagecount 两个数据属性的变化。当这些属性的值发生变化时,相关的回调函数将被触发,分别输出变化的消息。