在 Vuex 突变中访问 getter
Accessing getters within Vuex mutations
在 Vuex 存储突变中,是否可以访问 getter?考虑以下示例。
new Vuex.Store({
state: {
question: 'Is it possible to access getters within a Vuex mutation?'
},
mutations: {
askQuestion(state) {
// TODO: Get question from getter here
let question = '';
if (question) {
// ...
}
}
},
getters: {
getQuestion: (state) => {
return state.question;
}
}
});
当然这个例子没有多大意义,因为我可以直接在突变中的 state
对象上访问 question
属性,但我希望你能看到我想做什么。即有条件地操纵状态。
在突变中,this
是 undefined
并且 state
参数允许访问 state
对象,而不是存储的其余部分。
The documentation on mutations 没有提到任何关于这样做的事情。
我猜这是不可能的,除非我错过了什么?我想另一种方法是在商店外执行此逻辑(导致代码重复)或实施执行此操作的操作,因为操作可以访问整个商店上下文。我很确定这是一种更好的方法,即让突变专注于它实际应该做的事情;改变状态。这可能是我最终会做的,但我只是好奇是否有可能在突变中访问 getter?
Vuex 存储变异方法不提供对 getter 的直接访问。
这可能是不好的做法*,但您可以在提交变更时传递对 getters
的引用,如下所示:
actions: {
fooAction({commit, getters}, data) {
commit('FOO_MUTATION', {data, getters})
}
},
mutations: {
FOO_MUTATION(state, {data, getters}) {
console.log(getters);
}
}
* 最好的做法是让突变尽可能简单,只直接影响 Vuex 状态。这使得在无需考虑任何副作用的情况下更容易推理状态变化。现在,如果您遵循 vuex getter 的最佳实践,它们首先应该不会有任何副作用。但是,任何需要引用 getter 的逻辑都可以在一个操作中 运行,该操作具有对 getter 和状态的读取访问权限。然后该逻辑的输出可以传递给突变。因此,您 可以 将对 getters
对象的引用传递给突变,但没有必要这样做,而且它会搅浑水。
如果将 getter 和 mutation 放在单独的模块中,则可以在 mutation 中导入 getter,然后执行以下操作:
import getters from './getters'
askQuestion(state) {
const question = getters.getQuestion(state)
// etc
}
如果您将商店声明为表达式,您也可以在突变中引用商店对象,如下所示:
const Store = new Vuex.Store({
state: {...},
getters: {...},
mutations: {
myMutation(state, payload) {
//use the getter
Store.getters.getter
}
}
});
另一种解决方案是导入现有商店。假设您正在使用模块并且您的模块名为 foo
,您的增变器文件将如下所示 store/foo/mutations.js
:
import index from '../index'
export const askQuestion = (state, obj) => {
let store = index()
let getQuestion = store.getters['foo/getQuestion']
}
我并不是说这是最佳做法,但它似乎有效。
如果有人正在寻找一个简单的解决方案,@bbugh 写了一个解决这个问题的方法 here 只需让 mutations 和 getters 使用相同的函数:
function is_product_in_cart (state, product) {
return state.cart.products.indexOf(product) > -1
}
export default {
mutations: {
add_product_to_cart: function (state, product) {
if (is_product_in_cart(state, product)) {
return
}
state.cart.products.push(product)
}
},
getters: {
is_product_in_cart: (state) => (product) => is_product_in_cart(state, product)
}
}
使用 vuex 4 测试
const state = () => ({
some_state: 1
})
const getters = {
some_getter: state => state.some_state + 1
}
const mutations = {
GET_GETTER(state){
return getters.some_getter(state)
}
}
你组件中的某处
store.commit('GET_GETTER') // output: 2
在 Vuex 存储突变中,是否可以访问 getter?考虑以下示例。
new Vuex.Store({
state: {
question: 'Is it possible to access getters within a Vuex mutation?'
},
mutations: {
askQuestion(state) {
// TODO: Get question from getter here
let question = '';
if (question) {
// ...
}
}
},
getters: {
getQuestion: (state) => {
return state.question;
}
}
});
当然这个例子没有多大意义,因为我可以直接在突变中的 state
对象上访问 question
属性,但我希望你能看到我想做什么。即有条件地操纵状态。
在突变中,this
是 undefined
并且 state
参数允许访问 state
对象,而不是存储的其余部分。
The documentation on mutations 没有提到任何关于这样做的事情。
我猜这是不可能的,除非我错过了什么?我想另一种方法是在商店外执行此逻辑(导致代码重复)或实施执行此操作的操作,因为操作可以访问整个商店上下文。我很确定这是一种更好的方法,即让突变专注于它实际应该做的事情;改变状态。这可能是我最终会做的,但我只是好奇是否有可能在突变中访问 getter?
Vuex 存储变异方法不提供对 getter 的直接访问。
这可能是不好的做法*,但您可以在提交变更时传递对 getters
的引用,如下所示:
actions: {
fooAction({commit, getters}, data) {
commit('FOO_MUTATION', {data, getters})
}
},
mutations: {
FOO_MUTATION(state, {data, getters}) {
console.log(getters);
}
}
* 最好的做法是让突变尽可能简单,只直接影响 Vuex 状态。这使得在无需考虑任何副作用的情况下更容易推理状态变化。现在,如果您遵循 vuex getter 的最佳实践,它们首先应该不会有任何副作用。但是,任何需要引用 getter 的逻辑都可以在一个操作中 运行,该操作具有对 getter 和状态的读取访问权限。然后该逻辑的输出可以传递给突变。因此,您 可以 将对 getters
对象的引用传递给突变,但没有必要这样做,而且它会搅浑水。
如果将 getter 和 mutation 放在单独的模块中,则可以在 mutation 中导入 getter,然后执行以下操作:
import getters from './getters'
askQuestion(state) {
const question = getters.getQuestion(state)
// etc
}
如果您将商店声明为表达式,您也可以在突变中引用商店对象,如下所示:
const Store = new Vuex.Store({
state: {...},
getters: {...},
mutations: {
myMutation(state, payload) {
//use the getter
Store.getters.getter
}
}
});
另一种解决方案是导入现有商店。假设您正在使用模块并且您的模块名为 foo
,您的增变器文件将如下所示 store/foo/mutations.js
:
import index from '../index'
export const askQuestion = (state, obj) => {
let store = index()
let getQuestion = store.getters['foo/getQuestion']
}
我并不是说这是最佳做法,但它似乎有效。
如果有人正在寻找一个简单的解决方案,@bbugh 写了一个解决这个问题的方法 here 只需让 mutations 和 getters 使用相同的函数:
function is_product_in_cart (state, product) {
return state.cart.products.indexOf(product) > -1
}
export default {
mutations: {
add_product_to_cart: function (state, product) {
if (is_product_in_cart(state, product)) {
return
}
state.cart.products.push(product)
}
},
getters: {
is_product_in_cart: (state) => (product) => is_product_in_cart(state, product)
}
}
使用 vuex 4 测试
const state = () => ({
some_state: 1
})
const getters = {
some_getter: state => state.some_state + 1
}
const mutations = {
GET_GETTER(state){
return getters.some_getter(state)
}
}
你组件中的某处
store.commit('GET_GETTER') // output: 2