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 没有在计算属性上触发的主要内容,如果未能解决你的问题,请参考以下文章
vue的computed如果没有出现在模板里面,当它依赖的响应式属性发生变化,getter会触发吗?
vue的computed如果没有出现在模板里面,当它依赖的响应式属性发生变化,getter会触发吗?