1

I have this component which is managed by Bootstrap, specifically one of those nav-tabs widgets where, as you click Bootstrap shows and hides.

Bootstrap keeps track of which item was clicked on using the .active class. And, in Vue, I was to initialize a certain nav as being active on page load. But, once that's done, I want Vue leave the .active class management entirely up to Bootstrap.

<template>
<li class="nav-item"  v-if="toshow">
    <a class="nav-link" v-bind:id="'nav_' + link" 
    :class="{ active: isActive }" :aria-expanded="isActive"
    v-bind:href="'#'+link" data-toggle="tab" @click="onclick">
        {{label_}}
        <span v-if="badge" class="badge" :class="badge_level">{{badge}}</span>
        <span v-if="dynamic_badge" class="badge" :class="badge_level" >{{badge_value}}</span>
    </a>
</li>
</template>

At page load time, each component checks against Vuex and figures out if its id is in this.$store.state.active_tab - that's what sets .active.

    ,isActive: function(){

      //active_tab is where I specify which tab should be active
      //at first
      var res = this.link === this.$store.state.active_tab;

      return res;

    },

v-once is not a good fit, because the only thing I want to disable is the computation of .active (the badge children need to be updated live).

The component works, kinda. I think mostly because this.$store.state.active_tab's value does not mutate so Vue doesn't re-render. But it seems brittle at best.

What are best practices for using Vue to only set the initial values of certain variables, and then relinquishing control, without using v-once?

1 Answer 1

1

I would just access the a.nav-link element and add the .active class to its classList directly.

You can add a ref attribute to the a.nav-lank element link so:

<a class="nav-link" ref="link" ...>
  ...
</a>

And then add the .active class in the mounted hook:

mounted() {
  if (this.link === this.$store.state.active_tab) {
    this.$refs.link.classList.add('active');
  }
}
Sign up to request clarification or add additional context in comments.

3 Comments

but... wouldn't Vue go back and grab data.isActive again to populate .active, as soon as it wanted to re-render? In my example, I think I can live with that. But, suppose the component had another bound attribute/value, say, {{record_count}} that was expected to be kept live and synched. If the underlying data or store source for record_count was updated, then the component would be re-render for record_count, which is good. But active would also be updated again as per data.isActive, would it not?
Ah ok, I understand now. You want to set the active class initially, but not bind it. See my updated answer
nice. so, basically, avoid binding for this type of use case and initialize stuff in mounted. makes sense.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.