1

I'm new to vue.js, and I have a vue.js component that basically shows numbers from a data array when the button "Add elements" is clicked, the code is the following:

<template>
  <div>
    <button @click="updateCounter">Add elements</button>
    <div
      v-for="number in numsArray"
      :key="number"
      :ref="`${number}`"
    >
      <div>
        <p>{{ number }}</p>
      </div>
    </div>
  </div>
</template>

<script>
import { SocketUpdate as socketUp } from "./components/Data";

export default {
  name: "App",
  data() {
    return {
      numsArray: [],
      counter: 0,
    };
  },
  mounted() {
    console.log("REFS when mounted::", this.$refs);
  },
  beforeUpdate() {
    console.log("REFS before updated::", this.$refs);

  },
  updated() {
    console.log("REFS updated::", this.$refs);
  },
  methods: {
    updateCounter() {
      this.counter++;
      const copyOfArray = [...this.numsArray];
      copyOfArray.push(this.counter);
      this.numsArray = copyOfArray;
      console.log(this.numsArray);
    }
  },
};
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}
</style>

However, 1. when the button is clicked and new elements are added to the numsArray and displayed in the v-for div, the :ref="${number}" is never associated to the respective element, because when trying to print the this.$refs array in the mounted, updated or beforeUpdated hooks; that array empty (no refs) which means that the elements are created in the DOM, those numbers are visible, but the refs related to them are never created nor added to the this.$refs array. And 2. The console.log("REFS...", this.$refs); is only shown in the beforeUpdate when the button is clicked, and once in the mounted, so hows possible that the component passed through the beforeUpdate and not in the updated, if the data elements (numsArray in this case) were updated, do you know how exactly is the updated hook is invoked?

Thanks you!

  • 1
    Vue `v3.*`prior to `3.2.25` had a problem with `$refs` array in a v-for. Update your Vue version to `3.2.25` or above. This is also mentioned in [docs](https://vuejs.org/guide/essentials/template-refs.html#refs-inside-v-for). Alternatively, you can push the refs to the array using a ref function: `:ref="el => items.push(el)"` (assuming you define items in component as `const items = ref([])`) – tao Apr 29 '22 at 08:20
  • Actually, I have the 3.2.33 version installed, so it should work. Will try the other way. – David Galvis Sandoval Apr 29 '22 at 17:12
  • You haven't posted enough to repro, hence nobody can actually inspect the error. What is `import { SocketUpdate as socketUp } from "./components/Data";`? If I remove that import, it seems to work just fine: https://codesandbox.io/s/blissful-kate-m23v2q?file=/src/App.vue – tao Apr 29 '22 at 17:18
  • Simplified: https://codesandbox.io/s/charming-silence-0nd77n?file=/src/App.vue . Coposition API: https://codesandbox.io/s/competent-field-hihb2y?file=/src/App.vue – tao Apr 29 '22 at 17:33
  • Composition API with `state` (including computed `counter`) (`state` is roughly an equivalent to `data` , inside `setup`). The advantage is using `reactive` instead of `ref`, which no longer needs `.value` when used in component methods/hooks). I kinda like it: https://codesandbox.io/s/mutable-pond-v2jks3?file=/src/App.vue. Obviously, you can name `state` anything (e.g, `local`, `data`). And you're not limited to only one. – tao Apr 29 '22 at 17:41

0 Answers0