mik*_*pr4 8 javascript vue.js vuex vuejs2
这是一个带有参数化 getter的 Vuex Store 示例,我需要将其映射到 Vue 实例以在模板中使用。
const store = new Vuex.Store({
state: {
lower: 5,
higher: 10,
unrelated: 3
},
getters: {
inRange: state => value => {
console.log('inRange run')
return (state.lower <= value) && (state.higher >= value)
}
},
mutations: {
reduceLower: state => state.lower--,
incrementUnrelated: state => state.unrelated++
}
})
new Vue({
el: '#app',
template: "<div>{{ inRange(4) }}, {{ unrelated }}</div>",
store,
computed: Object.assign(
Vuex.mapGetters(['inRange']),
Vuex.mapState(['unrelated'])
),
})
setTimeout(function() {
console.log('reduceLower')
store.commit('reduceLower')
setTimeout(function() {
console.log('incrementUnrelated')
store.commit('incrementUnrelated')
}, 3000);
}, 3000);Run Code Online (Sandbox Code Playgroud)
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vuex/dist/vuex.js"></script>
<div id="app"></div>Run Code Online (Sandbox Code Playgroud)
首先,这似乎是有效的工作代码。但是考虑computed到是一组缓存的计算属性,我很好奇这种情况下的行为,是否有缓存?如果没有,是否需要考虑性能问题?即使该函数不会引起任何状态变化,它应该是一个method?
这是一种反模式吗?这个例子不是一个真实的例子,但我确实想在商店中集中逻辑。
更新
我更新了示例以说明lower/higher对inRangegetter 所基于的基础值的修改确实对 Vue 实例具有反应性(尽管没有被映射为状态)。我还包含了一个unrelated不属于计算的值,如果映射的 getter 被缓存,修改不相关的值不应触发再次调用 getter,但它确实如此。
我的结论是没有缓存,因此它的性能比传统的计算属性差,但它在功能上仍然是正确的。
关于这种模式是否存在任何缺陷,或者是否存在性能更好的问题,这个问题仍然悬而未决。
在我看来,这是一种反模式。这是一种汇集方法的奇怪方式。此外,不,这里没有缓存,因为inRange在不使用任何成员的情况下立即返回一个值(最终函数)state- 因此 Vue 检测到 0 个反应性依赖项。
Getter 不能以这种方式参数化,它们只能派生出基于状态的东西。因此,如果范围可以存储在状态中,那将起作用(并且会被缓存)。
类似的问题在这里:vuexjs getter with argument
既然你想集中这种行为 - 我认为你应该在一个单独的模块中这样做,也许作为一个混合。这也不会被缓存,因此您必须将它(和输入)包装在组件中computed或使用其他一些备忘录
像这样的东西:
import { inRange } from './state/methods';
import { mapGetters } from 'vuex';
const Example = Vue.extend({
data: {
rangeInput: 10
},
computed: {
...mapGetters(['lower', 'higher']),
inRange() {
return inRange(this.rangeInput, this.lower, this.higher);
}
}
});
Run Code Online (Sandbox Code Playgroud)