Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue.js - this.$refs.key returns an empty array or undefined instead of element

I have a component for dialog windows in Vue 2 that is listening to event tcs-show-confirm (it is the same event that shows the dialog, sets the show property to true - in a parent component):

  @Prop({ default: false })
  show: boolean;

  @Prop()
  buttons: Array<TcsDialogButton>;

  mounted() {

    this.$nextTick(function () {
      TcsEventBus.$on('tcs-show-confirm', () => {
        console.log(this.$refs.tcsdialbuttons);
      });
    });
  }

A html of the component is here (content of the footer slot is not replaced with another componet's html):

  ...
  <slot name="footer">
    <div v-if="buttons && buttons.length" ref="tcsdialbuttons" v-for="(button, index) in buttons">
      <button tabindex="0" class="tcs-button tcs-dialog__button" @click="$emit('close', button.emitString)">
        {{button.text}}
      </button>              
    </div>
    <div style="clear: both;"></div>
  </slot>
  ...

Problem is that console.log(this.$refs.tcsdialbuttons) shows an empty array [] with length 0. Why is that? How can I access the buttons and set a focus on the first one?


I also tried to change fat arrow function to normal function:

      TcsEventBus.$on('tcs-show-confirm', function() {
        console.log(this.$refs.tcsdialbuttons);
      });

But now it returns undefined.


I just found out that I cannot reference any of the elements in the component, even if it works in other components in my project. I don't understand..

like image 266
Incredible Avatar asked Oct 09 '17 12:10

Incredible


Video Answer


1 Answers

I strongly suggest considering these 2 good practices first:

  • https://vuejs.github.io/eslint-plugin-vue/rules/no-use-v-if-with-v-for.html
  • https://vuejs.github.io/eslint-plugin-vue/rules/require-v-for-key.html

Once that's taken care of, I'd suggest adding an index to your v-for and adding the :ref to the individual buttons so you can find each one of them in a function.

Working with array items via ref is rather well described here: this.$refs[("p" + index)].focus is not a function

You should be able to apply focus to the first button using something like this.$refs[button${index}][0].focus();

like image 139
ttntm Avatar answered Nov 14 '22 23:11

ttntm