web-dev-qa-db-ja.com

計算されたプロパティでv-ifがトリガーされない

私はvuexストアを持っています。 vuexストアの状態設定の変更時。 DOMを再レンダリングします。 vuexストアの状態設定が変更されるたびにcheckValueメソッドが呼び出されるようにします。

index.html

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

vueが初期化され、ストアもここにインポートされます

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 : {},
})

ストアの状態設定の変更時にDOMを変更する必要があるコンポーネント

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.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}
    }
}

li要素をクリックするとvuexストアが更新されるコンポーネント。

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>
7
Tomonso Ejang

メソッドはリアクティブではありません。つまり、メソッドは変更を追跡せず、何かが変更されても再実行しません。それはあなたが計算したものです。

したがって、必要なものを計算するために計算を使用する必要がありますが、計算はパラメータを受け入れず、オブジェクトを必要とするため、解決策はオブジェクトをプロパティとして受け入れる別のコンポーネントを作成し、そこでロジックを実行することです:

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>

そして、元のコンポーネントで:

<template>
    <my-other-component v-for="object in objects" :object="object" :preference="preference">
        <p>hello</p>
    </my-other-component>
</template>
4
Tomer

v-ifには関数呼び出しを含めないでください。関数が存在するだけで、v-if常に真実であること。 v-ifは変数または計算されたプロパティをテストする必要があり、動詞ではなく名詞である名前を持つ必要があります。 checkValueが設定をプロキシするだけの場合、なぜ必要なのですか。なぜv-if="preference"

2
bbsimonbb

あなたの主な問題はあなたの突然変異だと思います:VueJSは初期化中に反応性に必要なものすべてを作成するので、あなたのstate.componentsミューテーションペイロードを持つ新しいオブジェクトでオブジェクトをオーバーライドしようとすると、オブジェクトはすでに初期化されています。このオブジェクトは、反応性に対して構成されません( https://vuejs.org/v2/guide/reactivity.htmlを参照してください#Change-Detection-Caveats )。

突然変異を次のように変更してみてください:

mutations: {
  setPreference (state, payload) {
    Vue.set(state.preferenceList.components, 'object_id', payload.object_id);
  }
}
0
Florian Haider