Search code examples
twitter-bootstrapvue.jspopoverbootstrap-vue

$refs no longer registering after vue/bootstrap-vue update


I updated bootstrap-vue in my laravel project and noticed that functionality that was previously working is now broken. The code has remained the same so it's the only thing I can think of.

I'm currently on vue@2.5.16 and bootstrap-vue@2.17.3

The issue is with one of the $refs not being registered.

The project is old and I am not the original author. I am also relatively inexperienced with vue, so I don't know what has changed in vue and bootstrap-vue since this code was originally written.

The issue is with a component which wraps an input.

<b-container class="bv-example-row persons-second-part">
    <b-row class="">
        <b-col class="person" sm="2" v-for="(person, index) in persons" @click.prevent="doubleClick(person, index)" :key="index">
            <div v-show="person.deleted === false">
                <div v-show="(currentState === 2 || currentState === 3)" v-dragged="onDragged" :id="getId(index)" style="z-index: 999" class="jag-i-centrum-label-upper-left drag-me" v-text="person.name">
                </div>
            </div>
            <b-popover :target="getId(index)" triggers="focus" placement="top">
                <input v-model="person.comment" ref="popoverInput" placeholder="Skriv beskrivning">
            </b-popover>
        </b-col>
    </b-row>
</b-container>

Here are the relevant functions

methods: {
    doubleClick(person, index) {
      this.clicks++;
      setTimeout(() => {
        if (this.clicks == 2) this.openPopup(person, index);
        this.clicks = 0;
      }, 200);
    },

    openPopup(person, index) {
      person.showContainer = !person.showContainer;
      let that = this;
      setTimeout(function() {
        that.$root.$emit("bv::show::popover", "popover-" + index);
        const ref = that.getId(index);
        that.$refs.popoverInput[index].focus();
      }, 50);
    },

Other refs in the file are being registered. I assume this is not because the input element hasn't been added to the DOM when $refs is created. I this assumption correct?

Why did it work before? How do I get it to work again? I'm happy to provide more details and code


Solution

  • The problem wasn't so much in the code, as it was in the environment

    npm install vue@2.6 npm install vue-template-compiler@2.6

    Then all the original code worked again.

    I did change from using a setTimeout() to Vue.nextTick as I feel like it's a better solution than waiting an arbitrary amount of time.

    openPopup(person, index) {
          person.showContainer = !person.showContainer;
          let that = this;
          Vue.nextTick()
          .then(function () {
            const ref = that.getId(index);
            that.$root.$emit("bv::show::popover", ref);
            that.$refs.popoverInput[index].focus();
          })  
        },