Vue компонент загружается перед вызовом router.pu sh () - PullRequest
0 голосов
/ 23 февраля 2020

Я разрабатываю онлайн-игру для 2 игроков, используя Vue js и Firestore.

Когда нажата кнопка новой игры;

  • Я создаю новую комнату и сохраняю ее в базе данных.
  • Я проверяю изменения с помощью функции firestore docChanges (). Если создается новая комната, я перенаправляю текущего игрока и противника на страницу «Игра». vue.

Мои коды

Дом. vue

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");
          }
        });
      });
    },
  }
};
<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

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: {}
};
<template>
  <div id="game">
    <router-link
      :to="{name:'Home'}"
    >Return Home Page</router-link>
  </div>
</template>

Vue Маршрутизатор - индекс. js

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" или в новой игре есть был создан, найти противника из онлайн-пользователей и перенаправить обоих пользователей на страницу игры. Но здесь есть ошибка при перенаправлении. Страница не перенаправляется и выдает следующую ошибку.

Но я получаю ошибку ниже

Uncaught (в обещании)
NavigationDuplicated {_name: "NavigationDuplicated" , name: "NavigationDuplicated", сообщение: "Переход к текущему местоположению (" / game ") не разрешен"

Хотя текущая страница - Home. vue, она говорит текущая страница - игра. vue с надписью «Не разрешено go перейти на страницу« / game »».

Чтобы узнать подробности проблемы, я сделал следующее.

  • Когда я нажал на кнопку «Новая игра» в Home. vue, перед тем как перейти на страницу игры, я напечатал название текущей страницы статически и динамически с консоли.
  • В Страница Game. vue, когда компонент Game. vue был создан в методе create () , я напечатал название страницы статически и динамически с помощью консоли.

enter image description here

Как показано на рисунке, хотя A ctive page is Home. vue this. $ route.name показывает название страницы игры.

Я делаю перенаправление на игру. vue в firestore Функция docChanges () . Проблема должна быть здесь. Но я не смог решить источник проблемы.

Как мне решить проблему?

Примечания:

Ответы [ 2 ]

0 голосов
/ 23 февраля 2020

После наших комментариев по вашему вопросу, похоже, что проблемы возникают из-за того, что вы несколько раз (с this.$router.push("/game");) перенаправляете следующее l oop:

createGameAndOpponent() {
  db.collection("game_rooms").onSnapshot(snapshot => {
    snapshot.docChanges().forEach(change => {
      if (change.type == "added") {
        //...
        this.$router.push("/game");
      }
    });
  });
}

Вы должны прервать l oop в первый раз, когда вы встречаете change.type, что равно added. Поскольку docChanges() возвращает массив, вы можете сделать следующее:

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(), который запрашивает базу данных только один раз.
0 голосов
/ 23 февраля 2020

По-моему, у вас, похоже, две проблемы.

Можете ли вы быть уверены, что приведенный ниже код вызывает только один раз? вы используете forEach , может быть this.$router.push вызываться дважды. В вашем журнале показывается лог c, что обратный вызов был вызван дважды.

        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");
      }
    });

, если это так, вам может не понадобиться каждый, кроме простого for с return или использования [].some с верните true при попытке break вызова l oop.

...