响应式API中 computed 和之前的 computed 选项用法类似。
对于任何复杂逻辑,我们都可能使用计算属性。比如翻转字符串:
<template> <h1>{{ text }}h1> <button @click="change">count is: {{ state.count }}button> <p>Edit <code>components/HelloWorld.vuecode> to test hot module replacement.p>template><script>import { ref, reactive, computed } from 'vue'export default { name: 'HelloWorld', props: { msg: String }, setup(props){ let state = reactive({count: 0}) let text = computed(() => { return props.msg.split('').reverse().join('') }) const change = () => state.count++ return { state, change, text } }}script>
计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 msg 还没有发生改变,多次访问 text 计算属性会立即返回之前的计算结果,而不必再次执行函数。
通过 computed 传入一个 getter 函数,返回一个默认不可手动修改的 ref 对象。或者传入一个拥有 get 和 set 函数的对象,创建一个可手动修改的计算状态。
比如下面代码实现全选的逻辑:
<template> <input type="checkbox" id="all" v-model="checkedAll"> <label for="all">全部选择label> <div>div> <input type="checkbox" id="jack" value="Jack" v-model="checkedNames"> <label for="jack">Jacklabel> <input type="checkbox" id="john" value="John" v-model="checkedNames"> <label for="john">Johnlabel> <input type="checkbox" id="mike" value="Mike" v-model="checkedNames"> <label for="mike">Mikelabel> <br> <span>Checked names: {{ checkedNames }}span>template><script>import { ref, reactive, computed } from 'vue'export default { name: 'HelloWorld', props: { msg: String }, setup(props){ let checkedNames = ref([]) let checkedAll = computed({ get () { return checkedNames.value.length === 3 }, set (value) { if (value) { checkedNames.value = ['Jack', 'John', 'Mike'] } else { checkedNames.value = [] } } }) return { checkedNames, checkedAll } }}script>
计算属性的 getter 函数是没有副作用的。如果要执行副作用请使用 watch 来代替。关于 watch 的使用我会在下篇文章中介绍。
vue3往期内容:《学习vue3系列ref》《学习vue3系列reactive》