1

How do you affect an element in a child component from the parent component? My code below is a simplified version of what I am trying to achieve and the comments show various failed attempts.

Parent:

import InputText from "./InputText.js";

export default {

    components: { InputText },

    template: `

        {{ things }}<br><br>

        <input-text v-for="thing in things" :key="thing.id" :thing="thing" />
        
        <br><br>
        
        <button @click="focusBox()">TEST</button>
        
    `,

    data() {
        return {
            things: [{
                "id": 1,
                "name": ""
            }, {
                "id": 2,
                "name": ""
            }, {
                "id": 3,
                "name": ""
            }]
        }
    },

    methods: {
        focusBox() {
            // this.$refs.thing.id[2].focus();
            this.$nextTick(() => this.$refs.thing_2.focus());
        }
    }
}

Child:

export default {

    template: `
        <input type="text" v-model="thing.name" :ref="'thing_' + thing.id">
        <!-- <input type="text" v-model="thing.name" ref="thing.id"> -->
        <br>
    `,
    props: {
        thing: Object
    }

}

Many thanks in advance.

Alex
  • 79
  • 7
  • You can find a very good answer with explanation [here](https://stackoverflow.com/a/49677233/17099154) – Vasyl Dec 08 '22 at 18:38
  • Does this answer your question? [Vue - access nested childs using ref](https://stackoverflow.com/questions/49676654/vue-access-nested-childs-using-ref) – Vasyl Dec 08 '22 at 18:39
  • In the sample code; you didn't use `InputText` in your template at all. Another thing, where do you define the ref of `instrument_2`? – Raeisi Dec 08 '22 at 19:12

1 Answers1

2

You can watch for property changes:

const app = Vue.createApp({
  data() {
    return {
      things: [{"id": 1, "name": ""}, {"id": 2, "name": ""}, {"id": 3, "name": ""}],
      focused: null
    }
  },
})
app.component('inputText', {
  template: `
    <input type="text" v-model="thing.name" :ref="'thing'">
    <br>
  `,
  props: {
    thing: Object,
    focused: Boolean
  },
  watch: {
    focused(val, oldVal) {
      if(this.thing.id === val) this.$refs.thing.focus()
    },
  }
})
app.mount('#demo')
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<div id="demo">
  {{ things }}<br><br>
  <input-text v-for="thing in things" :key="thing.id" :thing="thing" :focused="focused"></input-text>
  <br>
  <p>insert thing id</p>
  <input type="number" v-model="focused" />
</div>
Nikola Pavicevic
  • 21,952
  • 9
  • 25
  • 46
  • Thanks for that bit of code for a beginner like me! I am currently going through the YouTube playlist on Vue3 from Laracasts, so it is really useful to see this.. Haven't got round to applying it to my app yet, but will post here with an answer to my specific problem when I have, thanks again ! – Alex Dec 14 '22 at 11:40