在调用 JSON.stringify() 之前 Vue 数据不可用
Vue data not available until JSON.stringify() is called
我不确定如何解决这个问题,因为其中涉及很多内容,而且这种行为是我以前从未在 JavaScript 或 Vue.js 中见过的
当然,我会尽量将代码保持在最关键的部分
我正在使用 vue-class-component(6.3.2),所以我的 Vue(2.5.17) 组件看起来像 classes :)
这个特定的组件看起来像这样:
import GameInterface from '@/GameInterface';
class GameComponent extends Vue {
public gameInterface = GameInterface();
public mounted() {
this.gameInterface.launch();
}
}
GameInterface return 具有启动方法和其他游戏变量的对象。
在游戏界面文件中,方法看起来像这样:
const GameInterface = function () {
const obj = {
gameState: {
players: {},
},
gameInitialized: false,
launch() => {
game = createMyGame(obj); // set gameInitialized to true
},
};
return obj;
}
export default GameInterface;
太棒了,它起作用了,该对象被传递到我的 Phaser 游戏 :) 并且它也被该方法 return 编辑了,这意味着 Vue 现在可以使用这个对象了。
在某些时候,我的 Vue class 中有一个 getter 方法,看起来像这样:
get currentPlayer() {
if (!this.gameInterface.gameInitialized) return null;
if (!this.gameInterface.gameState.players[this.user.id]) {
return null;
}
return this.gameInterface.gameState.players[this.user.id];
}
果然,null 被 return 编辑了,尽管播放器和 ID 显然在那里。
当我 console.log this.user.id
我得到 4
,并且 gameInterface.gameState.players
returns 一个带有 getters 的对象,这样的玩家:
{
4: { ... },
5: { ... },
}
好的,所以它不会 return 播放器,即使对象和键被正确传递...
但是我发现了一个非常奇怪的方法来解决"FIX"这个问题:像这样添加JSON.parse(JSON.stringify(gameState))
get currentPlayer() {
// ...
if (!this.gameInterface.gameState.players[this.user.id]) {
// add this line
JSON.stringify(this.gameInterface.gameState);
return null;
}
return this.gameInterface.gameState.players[this.user.id];
}
它成功地return为我们设置了当前玩家...奇怪不?
我的猜测是,当我们这样做时,我们 "bump" 对象,Vue 注意到一些变化因此正确更新对象。有人知道我在这里错过了什么吗?
在与一位朋友一起解决这个问题后,我发现潜在的问题是一个 JavaScript 特定的问题,涉及 Vue 的反应性质。
https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats
在文档的这一部分中,讨论了 Vue 的变更检测的警告:
Vue cannot detect property addition or deletion. Since Vue performs the getter/setter conversion process during instance initialization, a property must be present in the data object in order for Vue to convert it and make it reactive.
在我的游戏 运行 时,我这样设置玩家:
gameObj.gameState.players[user.id] = {...playerData}
我正在添加一个新的 属性,Vue 在初始化时还没有转换,Vue 没有检测到这个变化。这是我在开发游戏时没有考虑到的一个简单概念 运行-time.
为了正确设置新玩家,我决定使用展开运算符来更改整个 players
对象,Vue 会对此做出反应,反过来,Vue 会检测到我的像这样添加玩家:
gameObj.gameState.players = {
...gameObj.gameState.players,
[user.id]: {...playerData}
}
Vue 还讨论了另一种称为 $set
的方法,您可以在同一页上阅读。
我不确定如何解决这个问题,因为其中涉及很多内容,而且这种行为是我以前从未在 JavaScript 或 Vue.js 中见过的 当然,我会尽量将代码保持在最关键的部分
我正在使用 vue-class-component(6.3.2),所以我的 Vue(2.5.17) 组件看起来像 classes :) 这个特定的组件看起来像这样:
import GameInterface from '@/GameInterface';
class GameComponent extends Vue {
public gameInterface = GameInterface();
public mounted() {
this.gameInterface.launch();
}
}
GameInterface return 具有启动方法和其他游戏变量的对象。
在游戏界面文件中,方法看起来像这样:
const GameInterface = function () {
const obj = {
gameState: {
players: {},
},
gameInitialized: false,
launch() => {
game = createMyGame(obj); // set gameInitialized to true
},
};
return obj;
}
export default GameInterface;
太棒了,它起作用了,该对象被传递到我的 Phaser 游戏 :) 并且它也被该方法 return 编辑了,这意味着 Vue 现在可以使用这个对象了。
在某些时候,我的 Vue class 中有一个 getter 方法,看起来像这样:
get currentPlayer() {
if (!this.gameInterface.gameInitialized) return null;
if (!this.gameInterface.gameState.players[this.user.id]) {
return null;
}
return this.gameInterface.gameState.players[this.user.id];
}
果然,null 被 return 编辑了,尽管播放器和 ID 显然在那里。
当我 console.log this.user.id
我得到 4
,并且 gameInterface.gameState.players
returns 一个带有 getters 的对象,这样的玩家:
{
4: { ... },
5: { ... },
}
好的,所以它不会 return 播放器,即使对象和键被正确传递...
但是我发现了一个非常奇怪的方法来解决"FIX"这个问题:像这样添加JSON.parse(JSON.stringify(gameState))
get currentPlayer() {
// ...
if (!this.gameInterface.gameState.players[this.user.id]) {
// add this line
JSON.stringify(this.gameInterface.gameState);
return null;
}
return this.gameInterface.gameState.players[this.user.id];
}
它成功地return为我们设置了当前玩家...奇怪不?
我的猜测是,当我们这样做时,我们 "bump" 对象,Vue 注意到一些变化因此正确更新对象。有人知道我在这里错过了什么吗?
在与一位朋友一起解决这个问题后,我发现潜在的问题是一个 JavaScript 特定的问题,涉及 Vue 的反应性质。
https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats
在文档的这一部分中,讨论了 Vue 的变更检测的警告:
Vue cannot detect property addition or deletion. Since Vue performs the getter/setter conversion process during instance initialization, a property must be present in the data object in order for Vue to convert it and make it reactive.
在我的游戏 运行 时,我这样设置玩家:
gameObj.gameState.players[user.id] = {...playerData}
我正在添加一个新的 属性,Vue 在初始化时还没有转换,Vue 没有检测到这个变化。这是我在开发游戏时没有考虑到的一个简单概念 运行-time.
为了正确设置新玩家,我决定使用展开运算符来更改整个 players
对象,Vue 会对此做出反应,反过来,Vue 会检测到我的像这样添加玩家:
gameObj.gameState.players = {
...gameObj.gameState.players,
[user.id]: {...playerData}
}
Vue 还讨论了另一种称为 $set
的方法,您可以在同一页上阅读。