如何在Vue中传递ref给子组件且不被自动解包?
解决Vue+TypeScript中传递Ref类型Prop的自动解包问题
问题根源
Vue在模板中传递ref变量时会自动解包为其value值,所以父组件传c(ref<Canvas>类型)时,子组件实际收到的是Canvas实例,而非Ref<Canvas>对象,导致类型匹配报错。
解决方案
将ref包裹在非响应式普通对象中传递,避免Vue自动解包:
父组件代码
<script setup lang="ts"> import { ref } from 'vue'; import ChildComponent from './ChildComponent.vue'; import { Canvas } from 'fabric.js'; const theCanvasObject = new Canvas(); const c = ref<Canvas>(theCanvasObject); // 用普通对象包裹ref,规避自动解包 const canvasWrapper = { ref: c }; </script> <template> <ChildComponent :canvas="canvasWrapper.ref" /> </template>
子组件代码(保持不变)
<script setup lang="ts"> import { Ref } from 'vue'; import { Canvas } from 'fabric.js'; const props = defineProps<{ canvas: Ref<Canvas> }>(); // 直接通过props.canvas.value操作画布实例 </script>
简化写法(无需额外定义wrapper变量)
父组件模板可直接写表达式包裹ref:
<template> <ChildComponent :canvas="({ ref: c }).ref" /> </template>
注意事项
- 不要用
reactive包裹对象,因为reactive会自动解包内部的ref,传递的依然是Canvas实例而非Ref对象。 - 如果子组件无需直接操作ref本身,更推荐遵循Vue单向数据流原则:子组件prop定义为
Canvas类型,父组件传递c.value即可。
内容的提问来源于stack exchange,提问作者dotNET
相关产品推荐
相关产品推荐

