在Vue 3的 composition api 中,Computed 是如何工作的?
回答 2
浏览 2.4万
2022-03-13
我正试图让computed
在<script setup>
中工作。
<template>
<div>
<p>{{ whatever.get() }}</p>
</div>
</template>
<script setup>
import {computed} from "vue";
const whatever = computed({
get() {
console.log('check')
return 'check?';
}
})
</script>
console.log()
通过了,但return
语句似乎抛出了一个错误。
check
Vue warn]: Unhandled error during execution of render function
at <Cms>
Uncaught TypeError: $setup.whatever.get is not a function
at Proxy.render (app.js?id=d9e007128724c77a8d69ec76c6c081a0:39550:266)
at renderComponentRoot (app.js?id=d9e007128724c77a8d69ec76c6c081a0:25902:44)
at ReactiveEffect.componentUpdateFn [as fn] (app.js?id=d9e007128724c77a8d69ec76c6c081a0:30019:57)
at ReactiveEffect.run (app.js?id=d9e007128724c77a8d69ec76c6c081a0:23830:29)
at setupRenderEffect (app.js?id=d9e007128724c77a8d69ec76c6c081a0:30145:9)
at mountComponent (app.js?id=d9e007128724c77a8d69ec76c6c081a0:29928:9)
at processComponent (app.js?id=d9e007128724c77a8d69ec76c6c081a0:29886:17)
at patch (app.js?id=d9e007128724c77a8d69ec76c6c081a0:29487:21)
at render (app.js?id=d9e007128724c77a8d69ec76c6c081a0:30630:13)
at mount (app.js?id=d9e007128724c77a8d69ec76c6c081a0:28882:25)
我做错了什么呢?
2 个回答
#1楼
已采纳
得票数 23
在<template>
中,。
仅限getter:
{{ myVal }}
<p v-text="myVal" />
getter 和 setter:
<input v-model="myVal">
重要:请不要使用myVal.get()
或myVal.set(value)
!使用:
- 获取:
myVal
- 设置(分配):
myVal = value
在<script setup>
中:
仅限getter:
const someReactiveRef = ref(null)
const myVal = computed(() => someReactiveRef.value)
Getter & setter:
const someReactiveRef = ref(null)
const myVal = computed({
get() {
return someReactiveRef.value
},
set(val) {
someReactiveRef.value = val
}
})
// myVal can now be used in `v-model`
当反应式引用来自一个reactive()
对象的属性时,你不需要在setter或getter中添加.value
。例子:
const state = reactive({
someProp: null
})
const myVal = computed({
get() {
return store.someProp
},
set(val) {
store.someProp = val
}
})
请记住,你总是可以在reactive
里面使用computed
。例子。
const { createApp, reactive, computed, toRefs } = Vue
createApp({
setup() {
const state = reactive({
firstName: 'John W.',
lastName: 'Doe',
// getter + setter
fullName: computed({
get() {
return [state.firstName, state.lastName].join(' ')
},
set(val) {
const [last, ...rest] = val.split(' ').reverse()
state.firstName = rest.reverse().join(' ')
state.lastName = last
}
}),
// getter only:
name: computed(() => state.fullName)
})
return toRefs(state)
}
}).mount('#app')
<script src="https://unpkg.com/vue@3.2.40/dist/vue.global.prod.js"></script>
<div id="app">
<input v-model="firstName" />
<input v-model="lastName" />
<input v-model="fullName" />
<pre v-text="{ firstName, lastName, fullName, name }"></pre>
</div>
重要的是要注意。
- 当向
computed
传递一个非反应性引用时,Vue会警告你(the computed wrapper is unnecessary)。 - 当传递给它一个包含循环依赖关系的引用(例如:一个组件实例)时,Vue会再次警告你,并建议你使用
shallowRef
或markRaw
。
如何在脚本部分而不是在模板中访问myVal?
- Bill 2022-08-05
@Bill 在代码中访问计算的属性值,如setup函数,使用计算的属性名称,后加
.value
,例如myVal.value
。
- Maksim Shamihulau 2022-10-31
#2楼
得票数 1
计算过的属性作为字段出现。无论你是传入一个函数(如computed(() => /*...*/)
)还是传入一个带有get()
方法的对象(如果你不提供set()
方法,这里是等效的)。
你的模板应该简单地使用你的计算属性的名称,在这里是whatever
。
<template>
<div>
<p>{{ whatever }}</p>
</div>
</template>