Vue.js computed property not updating

前端 未结 7 724
猫巷女王i
猫巷女王i 2020-12-29 22:36

I\'m using a Vue.js computed property but am running into an issue: The computed method IS being called at the correct times, but the value returned by the computed

相关标签:
7条回答
  • 2020-12-29 22:47

    If your intention is for the computed property to update when project.classes.someSubProperty changes, that sub-property has to exist when the computed property is defined. Vue cannot detect property addition or deletion, only changes to existing properties.

    This has bitten me when using a Vuex store with en empty state object. My subsequent changes to the state would not result in computed properties that depend on it being re-evaluated. Adding explicit keys with null values to the Veux state solved that problem.

    I'm not sure whether explicit keys are feasible in your case but it might help explain why the computed property goes stale.

    Vue reactiviy docs, for more info: https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats

    0 讨论(0)
  • 2020-12-29 22:55

    If you add console.log before returning, you may be able to see computed value in filteredClasses.

    But DOM will not updated for some reason.

    Then you need to force to re-render DOM.

    The best way to re-render is just adding key as computed value like below.

    <div
      :key="JSON.stringify(filteredClasses)" 
      v-for="(klass, classIndex) in filteredClasses"
    >
      <ClassView
        :key="classIndex"
        :klass-raw="klass"
      />
    </div>
    

    Caution:

    Don’t use non-primitive values like objects and arrays as keys. Use string or numeric values instead.

    That is why I converted array filteredClasses to string. (There can be other array->string convert methods)

    And I also want to say that "It is recommended to provide a key attribute with v-for whenever possible".

    0 讨论(0)
  • 2020-12-29 22:56

    If you are adding properties to your returned object after vue has registered the object for reactivity then it won't know to listen to those new properties when they change. Here's a similar problem:

    let classes = [
        {
            my_prop: 'hello'
        },
        {
            my_prop: 'hello again'
        },
    ]
    

    If I load up this array into my vue instance, vue will add those properties to its reactivity system and be able to listen to them for changes. However, if I add new properties from within my computed function:

    computed: {
        computed_classes: {
            classes.map( entry => entry.new_prop = some_value )
        }
    }
    

    Any changes to new_prop won't cause vue to recompute the property, as we never actually added classes.new_prop to vues reactivity system.

    To answer your question, you'll need to construct your objects with all reactive properties present before passing them to vue - even if they are simply null. Anyone struggling with vues reactivity system really should read this link: https://vuejs.org/v2/guide/reactivity.html

    0 讨论(0)
  • 2020-12-29 23:00

    I had this issue when the value was undefined, then computed cannot detect it changing anymore. I fixed it by giving it an empty value, or random value since it will get updated. Hope it helps.

    0 讨论(0)
  • 2020-12-29 23:08

    I've ran into similar issue before and solved it by using a regular method instead of computed property. Just move everything into a method and return your ret. Official docs.

    0 讨论(0)
  • 2020-12-29 23:08

    You need to assign a unique key value to the list items in the v-for. Like so..

    <ClassView :klass-raw="klass" :key="klass.id"/>
    

    Otherwise, Vue doesn't know which items to udpate. Explanation here https://vuejs.org/v2/guide/list.html#key

    0 讨论(0)
提交回复
热议问题