core icon indicating copy to clipboard operation
core copied to clipboard

useTemplateRef warning appears after rollup packaging

Open bee1an opened this issue 10 months ago • 14 comments

Version

3.5.13

Reproduction link

stackblitz.com

Steps to reproduce

When the useTemplateRef argument has the same name as the variable that received it, a console warning appears after using rollup

What is expected?

No warnings

What is actually happening?

[Vue warn] Set operation on key "value" failed: target is readonly.

bee1an avatar Feb 11 '25 10:02 bee1an

You did not configure the NODE_ENV correctly for the build script.

KazariEX avatar Feb 11 '25 11:02 KazariEX

Encountered with same warning but in usage of our UI kit.

We have a layout component (VDefaultLayoutHeader) with code

<script lang="ts" setup>
const refHeader = useTemplateRef('refHeader')
</script>

<template>
    <header ref="refHeader" class="v-default-layout-header">
        ...
    </header>
</template>

Library is building without problems, but in project where we use this component console display warning message [Vue warn] Set operation on key "value" failed: target is readonly

yakudik avatar Feb 11 '25 16:02 yakudik

@yakudik Please provide a minimal reproduction.

edison1105 avatar Feb 12 '25 02:02 edison1105

You did not configure the NODE_ENV correctly for the build script.

Thanks for the answer. The same warning happens when I bundle vue as external content, although I set a fixed NODE_ENV, I know it looks weird in this example, but it really needs to be done in my project. Here's the latest example This is not an issue when the useTemplateRef argument string is different from the variable name that is expected to be returned like this:

Image

bee1an avatar Feb 12 '25 03:02 bee1an

Image The render function returned by setup is from the production build. However, the Vue you are using is in DEV mode, so a warning is displayed.

@yakudik The render function inside the VDefaultLayoutHeader is generated by the production build, but the Vue used in the project is in development mode. This results in a warning during development. However, after the project is built, the warning will no longer appear since everything will use the production version of Vue.

minimal reproduction with playground, the warning will disappear after changing from DEV to PROD.

edison1105 avatar Feb 12 '25 08:02 edison1105

@edison1105 Thanks for your answer. I solved my problem.

bee1an avatar Feb 13 '25 03:02 bee1an

@edison1105

It's true, this warning don't be showed in production, but the main problem is that we use templateRefs not only for VDefaultLayoutHeader.

We also have VDataTableTr, for example. This component has two templateRefs (on checkbox and row action)

Image

And this component, as you imagine, generate hundreds and hundreds of wirnings during local development)

yakudik avatar Feb 13 '25 13:02 yakudik

@yakudik

<script lang="ts" setup>
-const refHeader = useTemplateRef('refHeader')
+const headerRef = useTemplateRef('refHeader') // use a diff var name is a workaround
</script>

<template>
    <header ref="refHeader" class="v-default-layout-header">
        ...
    </header>
</template>

edison1105 avatar Feb 14 '25 00:02 edison1105

@edison1105 Is this a bug? Or is it my problem?

bee1an avatar Feb 14 '25 09:02 bee1an

@bee1an this is a bug but an edge case.

edison1105 avatar Feb 14 '25 09:02 edison1105

@edison1105 Thank you. I look forward to your fixing it

bee1an avatar Feb 14 '25 09:02 bee1an

@yakudik

Yes, and this is my current temporary solution, but i'll of course wait for this problem to be fixed

yakudik avatar Feb 14 '25 13:02 yakudik

I think the real issue here is that in vue 3.5.13 in development mode, setting a template ref while having a variable with the same in the script setup will try to assign the variable to the template ref. This is inconsistent with what is written in the documentation that this is before 3.5 usage.

Minimum example:

<script setup>
import {onMounted} from 'vue';
let div = null;
onMounted(() => console.log(div)); // div is not null but refers to the div node below
</script>

<template>
  <div ref="div"></div>
</template>

Console warning: Template ref "div" used on a non-ref value. It will not work in the production build.

A possible workaround is to name template ref using invalid identifier characters like #div.

char101 avatar Apr 03 '25 14:04 char101

Hi,

I'm encountering the same issue described in this PR (#13449) after migrating our component library to production builds.

Our situation:
Components using useTemplateRef() work correctly when running in source form (pre-bundling)

After bundling with Vite, we're seeing consistent warnings in development mode:

[Vue warn] Set operation on key "value" failed: target is readonly
This affects dozens of components throughout our library where we've used useTemplateRef()

Due to the scale of usage, it's impractical for us to modify each instance

Observations:
✅ Production builds work correctly (no warnings)
⚠️ Development builds with bundled components trigger warnings
⚠️ Source-form components (unbundled) work in both dev/prod

Could you please share:
The estimated timeline for merging this fix

Which Vue version will include the fix (v3.4.x or later?)

Any recommended workarounds until the fix ships

This is blocking our component library's production rollout. We'd be grateful for any updates on the release plan.

Thank you for your work on this fix!

zhouxianjun avatar Jun 09 '25 14:06 zhouxianjun

useTemplateRef 的绑定名称与模版 ref 为啥要设计为需要不一致,不明白,现在可以通过更改不一样的名称解决

joygqz avatar Aug 10 '25 13:08 joygqz

useTemplateRef 的绑定名称与模版 ref 为啥要设计为需要不一致,不明白,现在可以通过更改不一样的名称解决

This seems to be a problem with the compilation, I guess it might be to resolve the conflicts that occurred when obtaining template references through ref previously

bee1an avatar Aug 20 '25 02:08 bee1an