来自商店的数据中未定义的数组中的 Vue.js 对象
Posted
技术标签:
【中文标题】来自商店的数据中未定义的数组中的 Vue.js 对象【英文标题】:Vue.js Object in array undefined in data from store 【发布时间】:2020-07-15 13:56:05 【问题描述】:很抱歉,如果这真的很明显,但我是 Vue 新手,需要一些帮助。
我正在从我的存储中获取一组数据(帖子)并尝试控制台记录数组中的一个对象,但它每次都显示未定义。如果我控制台记录整个数组,它会返回正常。
我猜这与 created 钩子中的 console.log 之前没有加载数据有关?我已经尽我所能尝试了,这让我发疯了。任何帮助表示赞赏(下面的简化代码)。
<script>
export default
components: ,
computed:
posts()
return this.$store.state.posts;
,
created()
this.$store.dispatch("getPosts");
console.log(this.posts[0])
,
;
</script>
//Store code Below
export const state = () => (
posts: [],
)
export const mutations =
updatePosts: (state, posts) =>
state.posts = posts
export const actions =
async getPosts(
state,
commit,
dispatch
)
if (state.posts.length) return
try
let posts = await fetch(
`$siteURL/wp-json/wp/v2/video`
).then(res => res.json())
posts = posts
.filter(el => el.status === "publish")
.map((
acf,
id,
slug,
video_embed,
title,
date,
content
) => (
acf,
id,
slug,
video_embed,
title,
date,
content
))
commit("updatePosts", posts)
catch (err)
console.log(err)
【问题讨论】:
【参考方案1】:控制台行为说明
当您将对象或数组记录到控制台,然后单击以展开/查看属性时,控制台会在单击时向您显示属性现在,而不是日志的时间。因此,如果它们在记录后发生变化,您将看到新值。
怎么样?由于对象和数组是引用变量,因此控制台会存储引用,然后在您单击时自行更新。这仅适用于对象和数组。
相反,当您将原语记录到控制台时,您只能看到它在记录时的样子。
在 Chrome 中,您还会在控制台中的对象旁边看到一个蓝色小方块。当您将鼠标悬停时,它会告诉您,“下面的值刚刚被评估。”
这就是为什么您在记录一个项目时从未看到该值的原因,因为它是一个尚不存在的项目。但是posts
总是有一个引用,因为它被初始化为一个空数组。因此,在记录 posts
引用时,当您单击时,数据已经到达。
这里有一个demo 试图说明这一点。
【讨论】:
不客气。另外,请注意尝试通过 Vuex 操作承诺(await
或 .then
)访问 created
中新加载的数据的反模式。这是not considered a good practice。【参考方案2】:
如果要在 created() 钩子上获取正确的数据,则应在显示数据之前执行该操作。
-
在
created()
钩子中,您可以异步调度操作。
async created()
await this.$store.dispatch("getPosts");
console.log(this.posts[0])
,
-
您可以使用 javascript Promises。
async created()
this.$store.dispatch("getPosts").then(()=>
console.log(this.posts[0]);
);
,
【讨论】:
【参考方案3】:您需要按照文档https://vuex.vuejs.org/guide/actions.html#composing-actions 使用承诺。您的操作没有返回其获取数据的承诺,也没有在 console.logged 结果之前等待承诺解决。 Promise 是一个需要掌握的非常重要的概念。这是一个与您的代码基本匹配的示例,尽管我使用 setTimeout 而不是真正的 fetch 调用。
const store = new Vuex.Store(
state:
posts: []
,
getters:
itemList: (state) =>
return state.items;
,
mutations:
updatePosts: (state, posts) =>
state.posts = posts
,
actions: (actions =
async getPosts( state, commit, dispatch )
if (state.posts.length)
return Promise.resolve();
try
return new Promise(resolve => setTimeout(() =>
const posts = [ id: 42 ];
commit("updatePosts", posts);
resolve();
, 1000));
catch (err)
console.log(err);
)
);
const app = new Vue(
el: "#app",
computed:
posts()
return this.$store.state.posts;
,
created()
this.$store.dispatch("getPosts").then(() => console.log(this.posts[0]));
,
store
);
<script src="https://unpkg.com/vue@2.6.11/dist/vue.js"></script>
<script src="https://unpkg.com/vuex@2.5.0/dist/vuex.js"></script>
<div id="app">
</div>
【讨论】:
【参考方案4】:你得到一个 undefined 因为异步函数还没有填充状态。 对于异步数据,您应该始终使用 getter。
getter 的结果是根据它的依赖来缓存的,只有当它的一些依赖发生变化时才会重新评估。
Vuex Getters
// Store
export const getters =
get_posts(state)
return state.posts;
-
// component
computed:
posts()
return this.$store.getters['get_posts'];
;
【讨论】:
以上是关于来自商店的数据中未定义的数组中的 Vue.js 对象的主要内容,如果未能解决你的问题,请参考以下文章