Vue3带参计算属性报Boolean无调用签名错误如何解决
问题原因
Vue3的computed计算属性默认会执行传入的getter函数,将返回值作为属性的最终值,本身不会保留传入的函数引用。你将接收item参数的判断函数直接作为computed的getter传入后,Vue执行getter时没有传入对应参数,最终isSelected被赋值为布尔类型的判断结果,不是可调用函数,因此触发_ctx.isSelected is not a function的运行时错误,以及Type 'Boolean' has no call signatures的类型提示错误。
修复方案
根据使用场景可以选择以下三种实现方式:
方案1:计算属性返回高阶函数(推荐,符合带参数计算属性需求)
将computed的getter返回值设置为接收item参数的判断函数,既保留Vue计算属性的响应式缓存能力(仅当selectedItems变化时才会更新内部判断逻辑),也能支持传参调用,原有模板写法不需要修改。
选项式API写法:
computed: { isSelected() { return (item: MediaGalleryItemTypes) => { return this.selectedItems.some(e => e._id === item._id) } } }
组合式API写法:
const isSelected = computed(() => { return (item: MediaGalleryItemTypes) => { return selectedItems.value.some(e => e._id === item._id) } })
方案2:定义为普通方法(简单场景适用)
如果不需要计算属性的缓存能力,直接将判断逻辑定义为组件方法即可,方法本身就是可调用函数,不存在类型错误。
选项式API写法:
methods: { isSelected(item: MediaGalleryItemTypes) { return this.selectedItems.some(e => e._id === item._id) } }
组合式API写法:
const isSelected = (item: MediaGalleryItemTypes) => { return selectedItems.value.some(e => e._id === item._id) }
注意:该方案下每次组件重渲染都会重新生成函数引用,且每次调用都会执行数组遍历逻辑,仅适合数据量小、调用频次低的场景。
方案3:模板内联判断(逻辑极简单时可用)
如果判断逻辑仅在单个位置使用,不需要复用,可以直接将判断逻辑写在模板绑定属性上,不需要额外定义属性或方法:
<DocumentCard :is-selected="selectedItems.some(e => e._id === document._id)" />
内容的提问来源于stack exchange,提问作者Cedric Smith
相关产品推荐
相关产品推荐

