You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3中ref与prop同名为何仅构建阶段触发未定义报错

Vue3 同名Prop与模板Ref生产环境报错问题

问题表现

定义名为foobar的prop属性后,若创建同名模板ref,访问该ref时Vue会抛出foobar未定义的错误。该问题仅在执行npm run build构建生产包时出现,npm run dev启动开发服务时无异常。

将ref与prop设置为不同名称即可修复该问题,但官方文档未明确提及该命名限制,问题根因如下。

问题复现代码

<script setup>
defineProps({
    foobar: {
        type: String
    }
})
</script>

<template>
    <div>
        <div ref="foobar">
        {{ foobar }}
        </div>
    </div>
</template>

<script>
export default {
    data() {
        return {
        }
    },
    mounted() {
        // 抛出错误
        const el = this.$refs.foobar;
    }
}
</script>

正常运行代码示例

<script setup>
defineProps({
    foobar: {
        type: String
    }
})
</script>

<template>
    <div>
        <div ref="foobar2">
        {{ foobar }}
        </div>
    </div>
</template>

<script>
export default {
    data() {
        return {
        }
    },
    mounted() {
        // 正常访问
        const el = this.$refs.foobar2;
    }
}
</script>

根本原因

该问题由Vue3生产构建阶段的命名空间冲突导致,和开发/生产环境的编译策略差异直接相关:

  • 开发环境下Vue保留完整运行时逻辑,prop存储在组件实例的props字段、模板ref存储在$refs字段,二者完全隔离,同名不会产生冲突,因此访问正常。
  • 生产构建时Vue会启用编译优化,<script setup>中声明的prop会被直接提升为组件实例的顶层访问属性,减少属性查找路径以提升运行性能;此时如果模板ref和prop同名,编译阶段会误将ref的绑定目标识别为已经存在的prop变量,不会将对应的DOM节点写入$refs对象,最终访问this.$refs.foobar时就会得到undefined。
  • 该冲突仅出现在同时使用<script setup>和选项式<script>块的场景:如果全部逻辑都写在<script setup>中,编译阶段会检测到同名冲突直接抛出编译警告,但跨script块通过this.$refs访问时,编译阶段不会做跨块的命名校验,因此问题只会在生产构建后暴露。

Vue2的prop和ref存储逻辑完全独立,不存在该同名冲突问题。


内容的提问来源于stack exchange,提问作者Jamie Bradley

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 05:06:48