首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在调用router.push()之前加载Vue组件

在调用router.push()之前加载Vue组件
EN

Stack Overflow用户
提问于 2020-02-23 13:18:24
回答 2查看 1.6K关注 0票数 0

我正在开发一个2名玩家使用Vue js和Firestore的在线游戏。

单击新游戏按钮时的

  • 我创建了一个新房间并将其保存在数据库中。
  • 我使用docChanges ()函数检查这些更改。如果创建了一个新房间,我将当前玩家和对手重定向到Game.vue页面。

我的代码

Home.vue

代码语言:javascript
复制
import db from "@/firebase/init";
import Navbar from "@/components/Navbar";
export default {
  name: "Home",
  components: {
    Navbar
  },
  data() {
    return {
   
    };
  },

  methods: {

    newGame() {
      this.createGameRoom();
    },
    createGameRoom() {
      let gameNo = Date.now();
      db.collection("game_rooms")
        .add({
          gameNo: gameNo,
        })
        .then(() => {
          this.createGameAndOpponent();
        });
    },

    createGameAndOpponent() {
      db.collection("game_rooms").onSnapshot(snapshot => {
        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");
          }
        });
      });
    },
  }
};
代码语言:javascript
复制
<template>
  <div id="home">
    <Navbar />
    <div class="home container">
      <div class="card">
        <a class="waves-effect waves-light btn-large btn deep-purple darken-1" @click="newGame">
         New Game
        </a>
      </div>
    </div>
  </div>
</template>

Game.vue

代码语言:javascript
复制
export default {
  name: "Game",
  data() {
    return {};
  },
  created() {
    console.log("******************************");
    console.log("Current Page Name(Static):Game.vue");
    console.log("Current Page Name(Dynamic):" + this.$route.name);
    console.log("Game component created");
  },

  methods: {}
};
代码语言:javascript
复制
<template>
  <div id="game">
    <router-link
      :to="{name:'Home'}"
    >Return Home Page</router-link>
  </div>
</template>

Vue路由器- index.js

代码语言:javascript
复制
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import Game from '../views/Game.vue'
Vue.use(VueRouter)


const routes = [{
    path: '/',
    name: 'Home',
    component: Home,

}, {
    path: '/game',
    name: 'Game',
    component: Game,

}, ]

const router = new VueRouter({
    mode: 'history',
    base: process.env.BASE_URL,
    routes
})


export default router

我正在检查createGameAndOpponent函数中的内容:

如果"game_rooms“中有变化,或者已经创建了一个新游戏,请从在线用户中找到对手,并将两个用户都重定向到游戏页面。但是在重定向过程中出现了一个错误。该页未被重定向,并会出现以下错误。

但是我得到了下面的错误

未知(承诺)导航(_name:"NavigationDuplicated",名称:"NavigationDuplicated",消息:“不允许导航到当前位置("/game")

尽管当前页面是Home.vue,但它表示当前页面是game.vue,并说“不允许它进入'/game‘页面”。

为了了解问题的细节,我做了以下工作。

  • 当我点击Home.vue中的“新建游戏”按钮时,在进入游戏页面之前,我用控制台静态和动态地打印当前页面的名称。
  • 在Game.vue页面中,当在 created ()方法中创建Game.vue组件时,我使用控制台静态和动态地打印页面名称。

如图所示,虽然活动页面为Home.vue,但Home.vue显示了游戏页面的名称。

我将重定向到game.vue中的防火墙docChanges()函数。问题就在这里。但我解决不了问题的根源。

我怎样才能解决这个问题?

备注:

EN

回答 2

Stack Overflow用户

发布于 2020-02-23 13:45:07

在我看来,你似乎有两个问题。

您能确定下面的代码只调用一次吗?您使用的是forEach,可能是this.$router.push被调用两次。您的日志显示了回调已被调用两次的逻辑。

代码语言:javascript
复制
        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,而是一个简单的带有returnfor,或者在尝试对循环调用进行break时使用带有返回为真的[].some

票数 0
EN

Stack Overflow用户

发布于 2020-02-23 14:21:53

根据我们对您的问题的评论,问题似乎来自您在下面的循环中多次重定向(使用this.$router.push("/game");):

代码语言:javascript
复制
createGameAndOpponent() {
  db.collection("game_rooms").onSnapshot(snapshot => {
    snapshot.docChanges().forEach(change => {
      if (change.type == "added") {
        //...
        this.$router.push("/game");
      }
    });
  });
}

当您第一次遇到等于change.typeadded时,您应该中断循环。因为docChanges()返回一个数组,所以您可以这样做:

代码语言:javascript
复制
createGameAndOpponent() {
  db.collection("game_rooms").onSnapshot(snapshot => {
    for (const change of snapshot.docChanges()) {
      if (change.type == "added") {
        this.$router.push("/game");
        break;
      }
    });
  });
}

请注意以下额外要点:

  1. 因为,通过执行db.collection("game_rooms").onSnapshot设置了一个侦听器,所以应该从vue.js created钩子调用此方法(仅一次)。
  2. 另一方面,在getGameUsers()方法中,由于您只查询一次Firestore数据库(如果我没有弄错的话),最好使用get()方法,它只查询DB一次。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60362586

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档