gpt4 book ai didi

javascript - Vuex getter 中的 JSON 对象复制

转载 作者:数据小太阳 更新时间:2023-10-29 06:14:18 25 4
gpt4 key购买 nike

我发现 Vuex getter 中的 JSON 有一些奇怪的行为:它似乎导致了引用传递类型的问题。对于上下文——我正在开发一个音乐应用程序,它将有多个“场景”,每个场景都包含“轨道”集合(类似于 Ableton Live)。

这是我的 setter/getter :

  newTrack: state => {
let newTrack = JSON.parse(JSON.stringify(state.newTrackDefaults))
return newTrack
},

这是它引用的对象:

  newTrackDefaults: {
tune: [],
// and other properties
},

然后它被一个 Action 调用:

  setUpNewScene: context => {
let newScene = JSON.parse(JSON.stringify(context.state.newSceneDefaults))
let newTrack = context.getters.newTrack
console.log(newTrack) // this reveals that the problem is from the getter
newScene.tracks.push(newTrack)
context.commit('addNewScene', newScene)
}

所以这段代码的问题是,当我将项目(音高引用)添加到第一个场景的轨道,然后添加一个新场景时,场景自动接收与第一个场景。这反射(reflect)在 Vuex 状态(根据 DevTool),而不仅仅是渲染。此外,当用户更新第一个场景上的轨迹时,新场景上的轨迹也会相应改变。所以本能地,这感觉像是一种传递引用类型的错误。

通过各种 console.log 实验,我发现 getter 正在返回“已填充”轨道。它可以通过跳过 getter 并将操作编写为来修复:

  setUpNewScene: context => {
let newScene = JSON.parse(JSON.stringify(context.state.newSceneDefaults))
let newTrack = JSON.parse(JSON.stringify(context.state.newTrackDefaults))
console.log(newTrack) // this works fine
newScene.tracks.push(newTrack)
context.commit('addNewScene', newScene)
}

...所以虽然我有一个修复程序,但我对原始行为感到困惑。 getter 会干扰 JSON 函数吗?或者还有什么可能会导致这种情况?

最佳答案

Vuex getters 被缓存。

https://vuex.vuejs.org/en/getters.html

Like computed properties, a getter's result is cached based on its dependencies, and will only re-evaluate when some of its dependencies have changed.

如果它们的依赖关系没有改变,则 getter 返回它们最后返回的值。据推测,您不会改变 newTrackDefaults。这意味着 getter newTrack 永远不会更新。这意味着 context.getters.newTrack 每次都返回相同的对象。因此,您认为正在创建的所有"new"轨道实际上都是相同的轨道。

在处理默认值时,我喜欢创建一个返回默认值的函数。然后我可以随时随地调用该函数,不涉及时髦的缓存业务。

function newTrackDefaults() {
return {
tune:[],
// and other properties
}
}


setUpNewScene: context => {
let newScene = JSON.parse(JSON.stringify(context.state.newSceneDefaults))
let newTrack = newTrackDefaults()
newScene.tracks.push(newTrack)
context.commit('addNewScene', newScene)
}

有趣的事实:getter 可以返回函数,所以你也可以这样修复它。

newTrack: state => () => {
let newTrack = JSON.parse(JSON.stringify(state.newTrackDefaults))
return newTrack
},

现在你需要调用 getter,因为它现在是一个函数。

let newTrack = context.getters.newTrack()

关于javascript - Vuex getter 中的 JSON 对象复制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50070900/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com