简体   繁体   中英

Vue.js strange reactivity issue

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!

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 };
    });
  },

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM