引言
当我们开发复杂的 Vue.js 应用时,通常需要对数据进行计算和响应式地监听。Vue 3 的计算属性和侦听器提供了解决这些需求的完美方式。
本文将深入探讨 Vue 3 中的计算属性和侦听器,包括它们的定义、特点和使用方法,以及在实际应用中的使用技巧和最佳实践。
Vue 3 中的计算属性
在 Vue 3 中,计算属性通过 computed
函数进行定义,它接收一个简单对象或一个函数,其中可以包含 get
和 set
方法。get
方法用于计算属性的读取操作,即当计算属性在模板中被引用时,会触发 get
方法进行计算返回结果。set
方法用于计算属性的写入操作,即当计算属性在模板中被指定了新的值,会触发 set
方法进行处理。
下面是一个使用 Vue 3 的 computed
实现计算属性的例子:
<template>
<div>
<div>基础工资:{{ salary }}</div>
<div>绩效奖金:{{ bonus }}</div>
<div>总薪资:{{ totalSalary }}</div>
<input type="number" v-model="salary" /> <!-- 通过 `v-model` 绑定数据 -->
</div>
</template>
<script>
import { ref, computed } from 'vue';
export default {
setup() {
const salary = ref(10000); // 定义一个响应式数据
const bonus = computed(() => { // 定义一个计算属性
return Math.floor(salary.value / 10); // 计算方式为工资的10%
});
const totalSalary = computed({
get: () => { // 定义读取操作
return salary.value + bonus.value; // 计算基础工资和绩效奖金
},
set: (newValue) => { // 定义写入操作
salary.value = newValue - bonus.value; // 将新的薪资减去奖金得到基础工资
},
});
return { salary, bonus, totalSalary }; // 返回计算属性和响应式数据
},
};
</script>
在这个例子中,我们定义了一个 salary
响应式数据(使用了 ref
函数),并使用 computed
函数定义了两个计算属性 bonus
(绩效奖金)和 totalSalary
(总薪资)。bonus
的计算方式为工资的 10%,即基础工资除以 10,而 totalSalary
则由 salary
和 bonus
两个计算属性相加得到。
同时,我们还通过 v-model
语法将 salary
绑定到一个输入框中,可以方便地修改并即时计算出与之关联的计算属性。
在实际开发中,Vue 3 的计算属性可以方便地对响应式数据进行计算和复杂处理,并且与模板之间进行了解耦,提高了代码可维护性和阅读性。
Vue 3 中的侦听器
还有一种响应式数据的技术比计算属性更灵活,它就是侦听器。在 Vue 3 中,我们也可以通过 watch
函数来实现侦听器操作,并监听任意响应式数据的变化。watch
函数需要传入两个参数,第一个是要监听的响应式数据或计算属性,可以是简单类型或对象。第二个参数是一个函数,用于监听数据变化时的回调操作。与计算属性类似,watch
函数还可以配置参数来更加灵活地监听数据的变化情况。
下面是一个使用 Vue 3 的 watch
实现侦听器的例子:
<template>
<div>
<h2>当前求和为: {{ sum }}</h2>
<button @click="sum++">点我+1</button>
<h2>当前信息为: {{ msg }}</h2>
<button @click="msg += '~~'">修改信息</button>
<h2>姓名: {{ person.name }}</h2>
<h2>年龄: {{ person.age }}</h2>
<h2>薪资: {{ person.job.j1.salary }}</h2>
<button @click="person.name += '~'">修改姓名</button>
<button @click="person.age++">修改年龄</button>
<button @click="person.job.j1.salary++">涨薪</button>
</div>
</template>
<script>
import { ref, computed, watch, reactive } from 'vue';
export default {
setup() {
// 响应式数据
const sum = ref(0);
const msg = ref('你好啊');
const person = reactive({
name: '张三',
age: 18,
job: {
j1: {
salary: 20,
},
},
});
// 情况一:监听简单响应式数据的变化
watch(() => sum.value, (newValue, oldValue) => {
console.log('sum 值发生变化', newValue, oldValue);
});
// 情况二:监听多个响应式数据的变化
watch(
[sum, msg],
([newSum, newMsg], [oldSum, oldMsg]) => {
console.log('sum 和 msg 值发生变化', newSum, oldSum, newMsg, oldMsg);
}
);
// 情况三:监听响应式对象的某个属性的变化
watch(
() => person.name,
(newValue, oldValue) => {
console.log('person.name 值发生变化', newValue, oldValue);
}
);
// 情况四:监听响应式对象多个属性的变化
watch(
() => [person.name, person.age],
([newName, newAge], [oldName, oldAge]) => {
console.log(`person.name 和 person.age 值发生变化:${oldName}(${oldAge}) -> ${newName}(${newAge})`);
}
);
// 情况五:监听响应式对象某个深层属性的变化
watch(
() => person.job.j1.salary,
(newValue, oldValue) => {
console.log('person.job.j1.salary 值发生变化', newValue, oldValue);
},
{ deep: true } // 增加 deep 配置以深度监听
);
return { sum, msg, person };
},
};
</script>
在这个例子中,我们使用了 `watch` 函数分别对不同类型的响应式数据进行监听操作。通过函数参数和回调函数的配置,我们可以根据监听对象和监听操作具体处理不同的需求。
总之,在实际工作中,善于使用 Vue 3 的计算属性和侦听器,可以提高代码的可维护性、可读性和稳定性,更好地完成项目的开发需求。