v-if 没有在计算属性上触发

Posted

技术标签:

【中文标题】v-if 没有在计算属性上触发【英文标题】:v-if not triggered on computed property 【发布时间】:2018-05-14 02:01:03 【问题描述】:

我有一个 vuex 商店。关于 vuex 商店中状态偏好的变化。我想重新渲染 DOM。我希望每次 vuex 存储中的状态首选项发生变化时调用 checkValue 方法。

index.html

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

vue已经初始化,这里也导入store

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>

【问题讨论】:

你试过用v-show代替v-if吗? 不,我没有。我特别需要 v-if(类似行为) 你忘记在计算属性中返回一个值,所以它应该是return this.$store.getters.getPreference; 1.您需要从@VamsiKrishna 建议的计算中返回。 2. 只用preferences为什么还要checkValue,为什么不直接用computed呢? @fatman 我删除了一些代码以简要介绍问题。我想做的是,每次状态偏好发生变化时,我都需要在方法 checkValue 中计算一些逻辑。 checkvalue 根据逻辑返回 true 或 false。 【参考方案1】:

方法不是响应式的,这意味着它们不会跟踪更改并在发生更改时重新运行。这就是你计算的结果。

所以这意味着你需要使用计算来计算你需要的东西,但是计算不接受参数并且你需要对象,所以解决方案是创建另一个接受对象作为属性的组件,然后执行那里的逻辑:

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>

【讨论】:

【参考方案2】:

v-if 不应包含函数调用。只是函数的存在可能会导致v-if 始终为真。 v-if 应该测试一个变量或一个计算属性,它应该有一个名词而不是动词的名称!如果 checkValue 只是代理偏好,你为什么需要它。为什么不只是v-if="preference"

【讨论】:

我需要在 checkValue 中执行一些逻辑。我已经更新了问题。 是的。使用名词还是动词显然取决于您,但是您需要将其放入计算中,并且计算函数不带参数。你可能错过了一个重要的区别。 v-if 在“渲染”一侧。您无法控制它何时运行。这不是你调用的方法。当源数据发生变化时,它会“做出反应”。计算属性是相同的,因此您可以在 v-if 中使用计算属性。出于这个原因,名词也有更好的名字。方法不是这样的。它们会在您调用它们时运行,因此它们通常位于“更新”端,将更改返回到您的商店。 此答案中提供了非常好的信息。【参考方案3】:

我认为您的主要问题是您的突变: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);
  

【讨论】:

以上是关于v-if 没有在计算属性上触发的主要内容,如果未能解决你的问题,请参考以下文章

vue02

更改记录时,DS 模型记录上的 Ember 计算属性未触发

vue的computed如果没有出现在模板里面,当它依赖的响应式属性发生变化,getter会触发吗?

vue的computed如果没有出现在模板里面,当它依赖的响应式属性发生变化,getter会触发吗?

vue的computed如果没有出现在模板里面,当它依赖的响应式属性发生变化,getter会触发吗?

VUE计算属性、监听&深度监听、八大生命周期、v-if和v-show