Vue+TypeScript使用ref报Cannot create property 'value'错误如何解决
问题根因
你将组合式API的ref写法错误应用到了Vue类组件场景:类组件会自动将绑定到实例属性的Ref对象解包,你访问this.isOpen时拿到的已经是解包后的布尔值,而非Ref实例,因此访问.value会抛出Cannot create property 'value' on boolean 'false'错误,同时类型系统也会出现类型不匹配的问题。
解决方案
方案1:改用<script setup>组合式API写法(优先推荐)
这是Vue 3官方推荐的写法,不存在类组件的自动解包问题,类型匹配更顺畅:
<script setup lang="ts"> import { ref } from 'vue' import { Dialog, DialogPanel } from '@headlessui/vue' // 声明响应式变量 const isOpen = ref<boolean>(false) const toggleGuestList = (toggle: boolean) => { // script 内修改ref需要加.value isOpen.value = toggle } </script> <template> <button class="btn" @click="toggleGuestList(true)">View list</button> <!-- Dialog的v-model会自动解包ref --> <Dialog v-model="isOpen"> <DialogPanel> <!-- 弹窗内内容 --> </DialogPanel> </Dialog> </template>
方案2:保留类组件写法的修正
如果必须使用类组件,调整对应写法即可:
- 不需要访问
.value,直接给isOpen赋值,运行时已经自动解包 - 类型标注改为
boolean,和运行时的解包结果匹配
import { ref } from 'vue' import { Vue, Options } from 'vue-class-component' @Options({/* 组件配置项 */}) export default class YourComponent extends Vue { // 类型直接标注为boolean,和运行时解包结果对齐 private isOpen: boolean = ref(false) as unknown as boolean public toggleGuestList(toggle: boolean) { // 直接赋值即可,不需要加.value this.isOpen = toggle } }
方案3:类组件原生响应式写法(无需引入ref)
类组件本身支持直接声明类属性作为响应式变量,完全不需要引入ref:
import { Vue, Options } from 'vue-class-component' @Options({/* 组件配置项 */}) export default class YourComponent extends Vue { // 直接声明初始值,默认就是响应式变量 private isOpen = false public toggleGuestList(toggle: boolean) { this.isOpen = toggle } }
内容的提问来源于stack exchange,提问作者Simon Bob
相关产品推荐
相关产品推荐

