异步api调用后如何使用vuex getter
Posted
技术标签:
【中文标题】异步api调用后如何使用vuex getter【英文标题】:How to use vuex getter after async api call 【发布时间】:2019-05-15 13:53:44 【问题描述】:在您调度了一个改变状态的异步操作后,在 vuex 中调用 getter 的正确方法是什么?
我创建了一个示例 sn-p 来说明我的意思。如您所见,getLastNameByName()
失败,因为state.persons
为空。奇怪的是,如果我在那个 getter 中打印 state.persons
,它会在 api 调用之后打印数组。
预期的行为是 getLastNameByName('John')
返回 name: 'John', lastname: 'Smith'
const store = new Vuex.Store(
state:
persons: []
,
getters:
getLastNameByName: (state) => (name) =>
// console.log(state.persons) returns the state, yet I cannot call .find on it
return state.persons.find(element =>
return element.name === name
).lastname
,
,
mutations:
setPersons: (state, payload) =>
state.persons = [...payload]
,
actions:
async getPeople(commit)
return new Promise(function(resolve, reject)
setTimeout(async () =>
commit('setPersons', [
name: 'John',
lastname: 'Smith'
,
name: 'Sarah',
account: 'Appleseed'
])
resolve();
, 1000)
)
)
new Vue(
store,
el: '#app',
mounted()
this.$store.dispatch('getPeople').then( () =>
console.log(this.$store.getters.getLastNameByName('John'))
)
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/vuex"></script>
<div id="app">
</div>
【问题讨论】:
【参考方案1】:setTimeout() 不返回等待对象。检查承诺:
const store = new Vuex.Store(
state:
persons: []
,
getters:
getLastNameByName: (state) => (name) =>
return state.persons.find(element =>
return element.name === name
).lastname
,
,
mutations:
setPersons: (state, payload) =>
state.persons = [...payload]
,
actions:
async getPeople(commit)
return new Promise(function(resolve, reject)
setTimeout(async () =>
commit('setPersons', [
name: 'John',
lastname: 'Smith'
,
name: 'Sarah',
account: 'Appleseed'
])
resolve();
, 1000)
)
)
new Vue(
store,
el: '#app',
mounted()
this.$store.dispatch('getPeople').then(() =>
console.log(this.$store.getters.getLastNameByName('John'));
)
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/vuex"></script>
<div id="app">
</div>
无论如何,直接处理对存储的异步调用不是正确的方法。我认为在这种情况下更好的解决方案是watch
存储状态或使用computed
属性。
【讨论】:
我的错,我以为我以这种方式正确地重现了我的问题。该示例现在确实可以正常工作,所以我想这是因为我的项目中的其他内容。您能否详细说明您建议的更好的解决方案?在state.persons
上设置一个观察者并调用该手表中的吸气剂?但是,问题是我需要在另一个操作中使用该 getter。【参考方案2】:
在 jsbin.com 上试过,改进很少,没问题:
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Vue example</title>
<div id="app">
<show-person
:name="getLastName('John')"
></show-person>
</div>
<script src="https://unpkg.com/vue@2.5.21/dist/vue.min.js"></script>
<script src="https://unpkg.com/vuex@3.0.1/dist/vuex.min.js"></script>
<script>
const store = new Vuex.Store(
state:
persons: []
,
getters:
getLastName: state => name =>
return state.persons.length
? state.persons.find(element =>
return element.name === name
).lastname
: ''
,
mutations:
setPersons: (state, payload) =>
state.persons = [...payload]
,
actions:
getPeople: ( commit ) => new Promise(res =>
const data = [
name: 'John', lastname: 'Smith',
name: 'Sarah', account: 'Appleseed'
]
setTimeout(() =>
commit('setPersons', data)
res()
, 1000)
)
)
const ShowPerson =
functional: true,
render: (h, ctx) => h('p', ctx.props.name)
new Vue(
store,
el: '#app',
components:
ShowPerson
,
computed:
...Vuex.mapGetters([
'getLastName'
])
,
methods:
...Vuex.mapActions([
'getPeople'
])
,
created ()
this.getPeople()
)
</script>
【讨论】:
以上是关于异步api调用后如何使用vuex getter的主要内容,如果未能解决你的问题,请参考以下文章
测试调用 Getter 和 Mutations 的 Vuex 动作