Javascript 调用router.push()之前加载的Vue组件
我正在使用Vue js和Firestore为两名玩家开发一款在线游戏 单击新游戏按钮时强>Javascript 调用router.push()之前加载的Vue组件,javascript,firebase,vue.js,google-cloud-firestore,vue-router,Javascript,Firebase,Vue.js,Google Cloud Firestore,Vue Router,我正在使用Vue js和Firestore为两名玩家开发一款在线游戏 单击新游戏按钮时 我创建了一个新房间并将其保存在数据库中 我使用firestoredocchanges()函数检查更改。如果创建了一个新房间,我会将当前玩家和对手重定向到Game.vue页面 我的代码 Home.vue 从“@/firebase/init”导入数据库; 从“@/components/Navbar”导入Navbar; 导出默认值{ 姓名:“家”, 组成部分:{ 导航栏 }, 数据(){ 返回{ }; },
- 我创建了一个新房间并将其保存在数据库中
- 我使用firestoredocchanges()函数检查更改。如果创建了一个新房间,我会将当前玩家和对手重定向到Game.vue页面
从“@/firebase/init”导入数据库;
从“@/components/Navbar”导入Navbar;
导出默认值{
姓名:“家”,
组成部分:{
导航栏
},
数据(){
返回{
};
},
方法:{
新游戏(){
这个.createGameRoom();
},
createGameRoom(){
让gameNo=Date.now();
db.收藏(“游戏室”)
.添加({
gameNo:gameNo,
})
.然后(()=>{
这个。createGameandOperator();
});
},
CreateGameandOperator(){
db.collection(“游戏室”).onSnapshot(快照=>{
snapshot.docChanges().forEach(更改=>{
如果(change.type==“已添加”){
console.log(“*************************************”)
console.log('当前页面名称(静态):Home.vue')
console.log('当前页面名称(动态):'+此.$route.Name)
log(“推到游戏组件”)
console.log(“*************************************”)
这个。$router.push(“/game”);
}
});
});
},
}
};代码>
新游戏
在我看来,你似乎有两个问题
你能确定下面的代码只调用一次吗?您使用的是forEach,可能是this.$router.push
会被调用两次。您的日志显示回调已被调用两次的逻辑
snapshot.docChanges().forEach(change => {
if (change.type == "added") {
console.log("******************************")
console.log('Current Page Name(Static):Home.vue')
console.log('Current Page Name(Dynamic):'+this.$route.name)
console.log("Pushing to game component")
console.log("******************************")
this.$router.push("/game");
}
});
如果是这样的话,您可能不需要forEach,只需要一个简单的for
和return
,或者使用[]就可以了。当您尝试中断循环调用时,有些和return true一起返回。根据我们在您的问题下的评论,问题似乎是由于您多次重定向(使用this.$router.push)而造成的(“/game”);
)在以下循环中:
createGameAndOpponent() {
db.collection("game_rooms").onSnapshot(snapshot => {
snapshot.docChanges().forEach(change => {
if (change.type == "added") {
//...
this.$router.push("/game");
}
});
});
}
您应该在第一次遇到更改时中断循环。键入等于added
的。由于返回数组,您可以执行以下操作:
createGameAndOpponent() {
db.collection("game_rooms").onSnapshot(snapshot => {
for (const change of snapshot.docChanges()) {
if (change.type == "added") {
this.$router.push("/game");
break;
}
});
});
}
请注意以下额外要点:
由于通过执行db.collection(“game_rooms”).onSnapshot
设置侦听器,您应该从vue.js创建的
钩子调用此方法(仅一次)
另一方面,在getGameUsers()
方法中,由于您只查询Firestore数据库一次(如果我没有弄错的话),因此最好使用只查询DB一次的方法
这不是因为您执行了querySnapshot.docChanges().forEach()
,因此可能会多次重定向吗?如果在第一次change.type==“添加”后中断会发生什么情况
?要做到这一点,您需要使用另一种方法进行循环,请参阅,为了使问题的详细信息不会太长,我删除了所有不必要的代码。如果数据库中的玩家中有活动玩家,我将指向game.vue页面。我正在查看您共享的资源。@renaudtarnec我的意思是,您可以重定向在你的forEach
循环中多次访问/game
。我检查了你共享的源代码。我用“Break”解决了问题。但是游戏是实时的,所以我使用了“docChanges”方法。对两个用户进行控制和引导。但在此源代码中,只有活动用户正在重定向。是否有停止Foreach的方法?@RenaudTarnecI尝试了您所说的解决方法,但也出现了类似问题的错误。我发布该项目是为了更好地了解问题:。您可以向示例用户注册和登录。我刚刚使用sa进行了尝试示例用户,现在console.log
似乎是正确的。即console.log('当前页面名称(静态)…)
与console.log('当前页面名称(动态):…)匹配
在第一次单击时看起来很正确。但是当你返回主页并再次单击“新建游戏”按钮时,它会给出一个错误。我担心如果没有a,很难进一步帮助你。你的代码非常复杂和丰富,如果不复制整个应用程序,几乎不可能提供更多帮助(甚至是从您上面共享的应用程序的生成实例)。我尝试了您所说的方法,但仍然出现相同的错误。@HibritUsta break可以。但是您还应该解除vue组件destroy上的事件绑定。例如:beforeDestroy(){unconnectYourFireBase()}对不起,我不能完全理解你说的话。你能更详细地解释或说明你的意思吗?@iulo