我不确定如何解决此问题,因为其中有很多问题,而且这种行为是我从未在JavaScript或Vue.js中见过的 当然,我会尽量将代码保持在最关键的部分。
我正在使用vue-class-component(6.3.2),所以我的Vue(2.5.17)组件看起来像是类:) 这个特定的组件看起来像这样:
import GameInterface from '@/GameInterface';
class GameComponent extends Vue {
public gameInterface = GameInterface();
public mounted() {
this.gameInterface.launch();
}
}
GameInterface返回带有启动方法和其他游戏变量的对象。
在游戏界面中,文件to方法看起来像这样:
const GameInterface = function () {
const obj = {
gameState: {
players: {},
},
gameInitialized: false,
launch() => {
game = createMyGame(obj); // set gameInitialized to true
},
};
return obj;
}
export default GameInterface;
很好,它可以工作,该对象被传递到我的Phaser游戏中:),并且该方法还返回了该对象,这意味着Vue现在可以使用此对象。
有时候,我的Vue类中有一个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];
}
可以肯定的是,即使播放器和id很明显也返回了null。
当我console.log this.user.id
时,我得到4
,而gameInterface.gameState.players
返回一个带有吸气剂的对象,例如:
{
4: { ... },
5: { ... },
}
好的,因此即使正确传递了对象和键,它也不会返回播放器...
但是我发现了一种非常奇怪的方式来解决此问题:“修复” :像这样添加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];
}
它成功为我们返回了当前玩家...奇怪吗?
我的猜测是,当我们执行此操作时,我们会“碰撞”对象,因此Vue会注意到一些更改并正确更新对象。有人知道我在这里想念的吗?
答案 0 :(得分:0)
与一位朋友一起解决问题之后,我发现根本的问题是涉及Vue的反应性的JavaScript特定问题。
https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats
在文档的此部分中,讨论了Vue变更检测的警告:
Vue无法检测到属性的添加或删除。由于Vue在实例初始化期间执行getter / setter转换过程,因此数据对象中必须存在一个属性,以便Vue对其进行转换并使其具有反应性。
在游戏运行时,我会像这样设置玩家:
gameObj.gameState.players[user.id] = {...playerData}
我要添加一个新属性,该属性在初始化时Vue尚未转换,并且Vue无法检测到此更改。这是我在开发游戏运行时时没有考虑到的简单概念。
为了正确设置新玩家,我决定使用传播运算符更改Vue正在反应的players
对象的整体,然后Vue将检测到我的玩家正在像这样添加:
gameObj.gameState.players = {
...gameObj.gameState.players,
[user.id]: {...playerData}
}
Vue还讨论了另一种称为$set
的方法,您可以在同一页面上阅读该方法。