Vue、Vuex、JavaScript:includes() 无法按预期工作
Posted
技术标签:
【中文标题】Vue、Vuex、JavaScript:includes() 无法按预期工作【英文标题】:Vue, Vuex, JavaScript: includes() does not work as expected 【发布时间】:2019-11-24 09:12:43 【问题描述】:如果数组中不包含具有相同 id 的对象,我想将一些对象存储在数组中。无论如何,一切正常,直到我开始一次添加多个对象。
这里是使用Vuex的相关代码:
// filter function to check if element is already included
function checkForDuplicate(val)
for( let sessionItem of state.sessionExercises )
return sessionItem._id.includes(val._id);
;
// related array from vuex state.js
sessionExercises: [],
// vuex mutation to store exercises to session exercises
storeSessionExercises: (state, payload) =>
// Pre filtering exercises and prevent duplicated content
if( checkForDuplicate(payload) === true )
console.log("Exercise ist bereits für session registriert!");
else
state.sessionExercises.push(payload);
,
// Related vuex action
storeSessionExercises: ( commit , payload) =>
commit("storeSessionExercises", payload)
,
正如我之前写的,只要我添加一个对象,一切正常,checkForDuplicate() 将找到重复的对象并拒绝推送到数组。
现在有一种情况,我想将一组对象推送到数组,我通过数据库请求执行此操作,循环输出,提取对象并通过与我所做的相同的函数推送它们单个对象:
// get user related exercises from database + clear vuex storage + push db-data into vuex storage
addSessionWorkout: ( commit, dispatch , payload) =>
axios.post(payload.apiURL + "/exercises/workout", payload.data, headers: Authorization: "Bearer " + payload.token )
.then((result) =>
// loop through output array and
for( let exercise of result.data.exercises )
// push (unshift) new exercise creation to userExercises array of vuex storage
dispatch("storeSessionExercises", exercise)
;
)
.catch((error) =>
console.error(error)
);
,
推送也可以正常工作,但“过滤功能”却没有发挥作用。它将过滤第一个对象并拒绝将其推送到数组中,但是如果有第二个对象,即使已经包含相同的对象(相同的 ID),也会将其推送到数组中,我在这里看不到什么! ?让我疯了! :D
我理解它就像循环会将每个对象放入 checkForDuplicate() 并查看是否有重复它应该输出 true,因此该对象不会被推入数组。如果有人看到我目前不告诉我的内容。
【问题讨论】:
【参考方案1】:错误是您的过滤功能。你想循环你的 sessionExercises
并且只返回 true
如果它们中的任何一个匹配。但是,此时您返回第一次检查的结果。您的循环将始终只运行一次。
选项 1:仅在匹配时返回
function checkForDuplicate(val)
for( let sessionItem of state.sessionExercises )
if (sessionItem._id.includes(val._id))
return true;
return false;
;
选项 2:使用 es6 过滤器
storeSessionExercises: (state, payload) =>
var exercises = state.sessionExercises.filter(ex => (ex._id.includes(payload._id)));
if(exercises.length)
console.log("Exercise ist bereits für session registriert!");
else
state.sessionExercises.push(payload);
【讨论】:
不再只见树木不见森林! :) 那当然完全解决了它!非常感谢。【参考方案2】:我会更改 addSessionWorkout
操作,我会创建一个包含新旧条目的新练习数组,然后更新状态。
// related array from vuex state.js
sessionExercises: [],
// vuex mutation to store exercises to session exercises
storeSessionExercises: (state, payload) =>
state.sessionExercises = payload;
,
// Related vuex action
storeSessionExercises: ( commit , payload) =>
commit("storeSessionExercises", payload)
,
addSessionWorkout: async(
commit,
dispatch,
state
, payload) =>
const result = await axios.post(payload.apiURL + "/exercises/workout", payload.data,
headers:
Authorization: "Bearer " + payload.token
)
try
const newExercices = result.data.exercises.reduce((acc, nextItem) =>
const foundExcercise = acc.find(session => session.id === nextItem.id)
if (!foundExcercise)
return [...acc, nextItem]
return acc
, state.sessionExercises)
dispatch("storeSessionExercises", foundExcercise)
catch (e)
console.error(error)
,
【讨论】:
以上是关于Vue、Vuex、JavaScript:includes() 无法按预期工作的主要内容,如果未能解决你的问题,请参考以下文章
javascript vue vuex mapActions和mapMutations