Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

v-if not triggered on computed property

Tags:

vue.js

vuex

I have a vuex store. on change of state preference in the vuex store. i want to rerender the DOM. i want the checkValue method to be called everytime the state preference in the vuex store changes.

index.html

<div id="app">
    <my-component></my-component>
    <my-other-component></my-other-component>
</div>

vue is initialised, and also store is imported here

my_component.js

Vue.component('my-component',require('./MyComponent.vue'));
import store from "./store.js"
Vue.component('my-other-component',require('./MyOtherComponent.vue'));
import store from "./store.js"

new Vue({
    el : "#app",
    data : {},
    store,
    method : {},
})

component where DOM needs to be change on change of the state preference in store

MyComponent.vue

<template>
    <div v-for="object in objects" v-if="checkValue(object)">
        <p>hello</p>
    </div>
</template>


<script>
    methods : {
        checkValue : function(object) {
            if(this.preference) {
                // perform some logic on preference
                // logic results true or false
                // return the result
            }
        }
    },

    computed : {
        preference : function() {
            return this.$store.getters.getPreference;
        }
    }


</script>

Vuex store file

store.js

const store = new Vuex.Store({
state : {
    preferenceList : {components : {}},
},
getters : {
    getPreference : state => {
        return state.preferenceList;
    }
},
mutations : {
    setPreference : (state, payload) {
        state.preference['component'] = {object_id : payload.object_id}
    }
}

component from where the vuex store is updated on clicking in the li element.

MyOtherComponent.vue

<div>
    <li v-for="component in components" @click="componentClicked(object)">
    </li>
</div>


<script type="text/javascript">
    methods : {
        componentClicked : function(object) {
            let payload = {};
            payload.object_id = object.id;
            this.$store.commit('setPreference', payload);
        }
    }
</script>
like image 802
Tomonso Ejang Avatar asked Nov 30 '17 07:11

Tomonso Ejang


People also ask

Are computed properties reactive?

Once we've created our computed prop, we can access it like we would any other prop. This is because computed props are reactive properties, along with regular props and data.

Does V-if trigger mounted?

Lifecycle Hooks When Vue renders a component because the v-if expression became truthy, it triggers both the 'created' and 'mounted' hooks. For example, the below code will print both 'Created! ' and 'Mounted!

Can we pass parameters to computed property?

For passing the parameters to the computed property, we just pass the parameters as we do for the function.

What is the difference between V-if and V-show?

The key difference is that v-if conditionally renders elements and v-show conditionally displayselements. This means that v-if will actually destroy and recreate elements when the conditional is toggled. Meanwhile, v-show will always keep the element in the DOM and will only toggle its display by changing its CSS.


1 Answers

Methods are not reactive,

which means they will not track changes and re-run when something changes. That's what you have computed for.

So it means you need to use a computed to calculate what you need, but computed does not accept parameters and you need the object, so the solution is to create another component that accepts the object as a property and then perform the logic there:

MyOtherComponent.vue:

<template>
    <div v-if="checkValue">
        <p>hello</p>
    </div>
</template>


<script>
    props:['object','preference']
    computed : {
        checkValue : function() {
             if(this.preference) {
               // perform some logic on preference
               // logic results true or false
               return true
             }
             
             return false
        }
    }


</script>

And then in the original component:

<template>
    <my-other-component v-for="object in objects" :object="object" :preference="preference">
        <p>hello</p>
    </my-other-component>
</template>
like image 171
Tomer Avatar answered Nov 16 '22 03:11

Tomer