1

I'm at my wits end here, I could really use some troubleshooting help.

I have some reactivity issues suddenly, after moving code from my master / root App.vue to a Home.vue "view" file.

Take the following App.vue template syntax:

  <div id="app">
    <Header15 />
    <router-view />
    <UtilsBar />
    <Footer15 />
  </div>
</template>

The problematic template syntax snippet defined in my Home.vue file:

<ul class="filter-list">
  <li class="filter-list__litem" v-for="theme in themeFilterButtons" :key="theme.id">
    <a class="filter-list__link" :class="{ 'on': theme.isActive }" :href="'#'+theme.id" @click.prevent="onFilterSelect('theme', theme.id)">
      {{ theme.isActive }}<br />
      {{ theme.text }}
    </a>
  </li>

themeFilterButtons, is a computed array of objects.

computed: {
  themeFilterButtons() {
    return this.filters.themes.map((theme) => {
      return { ...theme, isActive: false };
    });
  }
}

The new array, references an array (themes) from my filters object; it's defined in my data as such:

data() {
  return {
    filters: {
      themes: [
        { id: 113, text: 'First World War' },
        { id: 214, text: 'Second World War' }
      ]
    }
  }
}

The onFilterSelect method bound to the click event eventually calls another method, filterBtnSelToggle. That method, takes care of toggling a selected class (.on) by toggling the isActive property on the object.

For the sake of troubleshooting, I've simplified the function to attempt performing the menial task of setting the isActive property on the first array index to true. Since it's initially set to false, clicking any button should change the property to true. The template view, (v-for) will not update no matter how I set that value. I tried all these and nothing updating the markup.

onFilterSelect(cat, id) {
  // Say I wanted to set isActive: true on the first array item.
  this.themeFilterButtons[0].isActive = true; // < Doesn't work.
  this.$set(this.themeFilterButtons[0], 'isActive', true); // < Nope, also doesn't work.
  console.log('this.themeFilterButtons[0].isActive'); // Returns true.
}

Anything I log to console returns what I expect, it's just the template (markup) stuff that doesn't get updated.

Like I said, what's strange is this was working and continues to work if I move that logic back into the main App.vue file...

Any help is much appreciated!

0

2 Answers 2

2

under this circumstances, computed property depends on this.filters.themes and you always set isActiv false. so you can set themeFilterButtons as a data property and it can work

  // delete computed Code block set themeFilterButtons property in data 
  mounted() {
    this.themeFilterButtons = this.filters.themes.map((theme) => {
      return { ...theme, isActive: false };
    });
  },
Sign up to request clarification or add additional context in comments.

2 Comments

Nice! This works. I'll admit, I need to brush up skills on when to use different lifecycle hooks, etc. I presume this is some way or another explains why the code was working in my App.js but not Home.js "view". Although this works, is doing what I'm doing in that mounted lifecycle hook bad practice or likely to become problematic?
in this case, code in created lifecycle is also ok, When it comes to data property or property, the create and the mounted are not so different.if you want use ref ,use mounted only
-1

You can try to use the getter setter computed property.

computed: {
  themeFilterButtons: {
    get () {
      return this.filters.themes.map((theme) => {
        return { ...theme, isActive: false };
      });
    }
    set (val) {
      this.filters = val
    }
  }
}

But, a better way would be defining isActive in the data first

1 Comment

OP isn't using v-model or anything else that would require a setter

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.