Open Nicolas-Yazzoom opened 1 month ago
a minimal reproduction: Playground
as a workaround, use instance.refs
(see the playground demo above) or function refs.
I could not get your workaround to work at first. After some investigation I found a few more inconsistencies which might be related to this issue: Playground. Click the button in both DEV and PROD modes and compare the result in the console.
What I was doing first was init'ing the ref as an empty array according to the docs. Your playground init'ed them like this: ref()
. I'm unsure what this does as the docs don't mention this.
Here are the results in a table:
Variable | ref in <template> refers to variable |
ref in <script> init'ed as array |
ref.value in DEV |
instance.refs in DEV |
ref.value in PROD |
instance.refs in PROD |
---|---|---|---|---|---|---|
testA | Yes | Yes | ✔️ | Missing | Empty array | ✔️ |
testB | Yes | No | ✔️ | ✔️ | undefined |
✔️ |
testC | No | Yes | ✔️ | Missing | ✔️ | Missing |
testD | No | No | ✔️ | ✔️ | ✔️ | Present as proxy. A and B are not a proxy and D was not a proxy during DEV. |
This is a duplicate of #4866
As said, this is mostly a design flaw and there's no real fix for it. I am thinking of providing a dedicate useTemplateRef
function in 3.5.
I was able to work around this issue like this. I updated my code to look like the testB
case. I'm using getCurrentInstance()
as suggested by @jh-leong which works both in DEV and PROD as long as you DON'T define const testB = ref([])
. Defining the ref in <script setup>
puts you in case A which breaks during DEV.
Vue version
3.4.31
Link to minimal reproduction
https://stackblitz.com/edit/vitejs-vite-auh6nk?file=src%2FApp.vue,src%2Fcomponents%2FTestA.vue,src%2Fcomponents%2FTestB.vue&terminal=dev
Steps to reproduce
Observe behavior during dev:
TestB
can be inspected in the console using the logged variablelistOfB
.Observe behavior after building:
TestB
is not included in thelistOfB
variable.What is expected?
In both cases the exposed method from
TestB.vue
should be called, showing the alert. In both cases listOfB should contain a reference to theTestB
instance.What is actually happening?
In the production build, the alert is not shown because
listOfB
does not contain a reference to the instance ofTestB
. Because of this, it cannot call the exposed method.System Info
(Ran this in the StackBlitz terminal)
Any additional comments?
The docs do not mention dynamically setting a template ref (using
:ref=" "
instead ofref=" "
) is not allowed.