2

I have two entities: categories and subcategories and two lists. When user selects a category I display subcategory list.

At first try it works fine, but when I change category I got old subcategory list.

Both categories and subcategories are in vuex store.

I tried to calculated subcategories next ways:

  1. Computed property
  2. When user selects a category I invoke a method, which filters subcategories by category_id and returns new list

Nothing worked for me. Here is an example of computed property:

subCategories() {
  return this.getClothingSubCategories.filter((subCategory) => {
    return subCategory.clothing_category_id === this.category.clothing_category_id
  })
},

Where this.getClothingSubCategories is a vuex getter.

What's weird is that both in vue plugin (in chrome developer tools) and console I got the list updated, but in html the list is old.

Here is how I display the list:

<VuePerfectScrollbar class="categories"
                     v-if="showSubCategories"
                     v-once>
  <ul>
    <li v-for="subCategory in subCategories"
        :key="subCategory.clothing_subcategory_id"
        @click="selectSubCategory(subCategory)">
      <div class="title">{{ subCategory.title }}</div>
      <div class="arrow">></div>
    </li>
  </ul>
</VuePerfectScrollbar>

So, the subCategories property relies on category object, which I set simply:

selectCategory(category) {
  this.category = category
},

When user selects a category.

I specified :key, tried different approaches but nothing worked, I always get the old list of subCategories.

What could be the reason?

update

Vuex getter:

export const getClothingSubCategories = (state) => {
  return state.clothingSubCategories
}

Component data:

data() {
    return {
      gender: 'female',
      category: null,
      subCategory: null,
      good: null,

      filters: {
        gender: 'female',
        clothing_subcategory_id: null
      }
    }
  },
8
  • Show the code for the getter this.getClothingSubCategories, and most importantly, where you change the category in the Vuex store: the mutation and the code (in a component) that calls that mutation. Commented Mar 31, 2018 at 23:28
  • I change category only in component. When user selects a category from category list, I set components data (this.category = category) Commented Mar 31, 2018 at 23:29
  • Can you paste the data of the component? Commented Mar 31, 2018 at 23:34
  • Sure, updated my question Commented Mar 31, 2018 at 23:36
  • Having the category initially null, doesn't this.category.clothing_category_id in the subCategories computed throw an exception? Commented Mar 31, 2018 at 23:42

1 Answer 1

1

Consider your declaration:

<VuePerfectScrollbar class="categories"
                     v-if="showSubCategories"
                     v-once>
  <ul>
    <li v-for="subCategory in subCategories"
        :key="subCategory.clothing_subcategory_id"
        @click="selectSubCategory(subCategory)">
      <div class="title">{{ subCategory.title }}</div>
      <div class="arrow">></div>
    </li>
  </ul>
</VuePerfectScrollbar>

The subCategories value, which is a computed property:

subCategories() {
  return this.getClothingSubCategories.filter((subCategory) => {
    return subCategory.clothing_category_id === this.category.clothing_category_id
  })
},

is supposed to be updated whenever category changes.

As you reported, it does. As it should.

Your problem, though is:

v-once

Details:

Render the element and component once only. On subsequent re-renders, the element/component and all its children will be treated as static content and skipped. This can be used to optimize update performance.

That is, as soon as Vue renders the subcategory collection the first time it "freezes" it. Basically, because of v-once it will never be updated again.

Solution: remove v-once.

I suggest you remove from other places in your code as well. Any element you want to be updated should not have v-once.

Sign up to request clarification or add additional context in comments.

2 Comments

Owe you a drink or so!
Haha! If I ever go to Russia, let's make sure that debt is payed!

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.