Как исправить неверный компонент vue-router на правильном маршруте - PullRequest
0 голосов
/ 11 февраля 2019

Я настраиваю приложение vuejs, которое должно перенаправлять на некоторые заранее определенные страницы.Все маршруты работают идеально, кроме «завершено» и «allCompleted»

Когда все квесты завершены, пользователь должен быть перенаправлен на маршрут allCompleted.

Каков фактический результат:

Когда пользователь завершает квест, приложение перенаправляется на «выполнить».Но это делает компонент allCompleted.

Когда все квесты завершены, мы перенаправляемся на «allCompleted».

Так что я не знаю, что я делаю неправильно.

Мы думаем, что прочитали все посты в интернете, касающиеся vue-router и рендеринга неправильных компонентов, и большинство из них посвящены опечаткам или отображению дочерних элементов в представлении sub-router.Но это не так в нашем приложении.

router.ts

import Vue from "vue";
import Router from "vue-router";
import { QuestsView, QuestCompleteView } from "@/modules/quests";
import QuestDetailView from "../modules/quests/views/QuestDetailView.vue";
import QuestAllCompletedView from "../modules/quests/views/QuestAllCompletedView.vue";

import Register from "../modules/auth/components/Register.vue";
import Login from "../modules/auth/components/Login.vue";
import PasswordForgotten from "../modules/auth/components/PasswordForgotten.vue";
import ContactsView from "../modules/contacts/views/ContactsView.vue";
import authGuard from "./auth-guard";
import LeaderBoardView from "@/modules/leaderboard/views/LeaderBoardView.vue";

Vue.use(Router);

export default new Router({
  mode: "history",
  base: process.env.BASE_URL,
  routes: [
    {
      path: "*",
      redirect: "/quests"
    },
    {
      path: "/register",
      name: "register",
      component: Register
    },
    {
      path: "/login",
      name: "login",
      component: Login
    },
    {
      path: "/passwordForgotten",
      name: "passwordForgotten",
      component: PasswordForgotten
    },
    {
      path: "/quests",
      name: "quests",
      component: QuestsView,
      beforeEnter: authGuard
    },
    {
      path: "/quests/:id",
      name: "quest detail",
      component: QuestDetailView,
      beforeEnter: authGuard
    },
    {
      path: "/contacts",
      name: "contacts",
      component: ContactsView,
      beforeEnter: authGuard
    },
    {
      path: "/info",
      name: "info",
      beforeEnter: authGuard
    },
    {
      path: "/leaderboard",
      name: "leaderboard",
      component: LeaderBoardView,
      beforeEnter: authGuard
    },
    {
      path: "/complete",
      name: "complete",
      component: QuestCompleteView,
    },
    {
      path: "/allCompleted",
      name: "allCompleted",
      component: QuestAllCompletedView
    }
  ]
});

QuestList.vue

export default class Quests extends Vue {
  @QuestsGetter quests: Quest[];
  @QuestsGetter loading: boolean;
  @QuestsAction loadQuests;

  @Watch("quests")
  onQuestsChange(value: Quest[]): void {
    const completedQuests = value.filter(
      quest => quest.status === QuestStatus.COMPLETED
    );
    if (completedQuests.length === this.quests.length) {
      this.$router.push("/allCompleted"); // Todo: Create allCompleted view
    }
  }

  created() {
    this.loadQuests();
  }
}
</script>

QuestAllCompletedView.vue

<template>
  <div class="quest-all-complete-view">
    <router-link to="quests">
      <div class="all-reward all-reward--image"></div>
    </router-link>
  </div>
</template>

<script lang="ts">
import { Vue } from "vue-property-decorator";

export default class QuestAllCompletedView extends Vue {}
</script>

<style scoped lang="scss">
@import "~@/styles/variables";
.quest-all-complete-view {
  width: 100%;

  .all-reward {
    width: auto;
    height: 56rem;

    &--image {
      background: url("~@/assets/images/reward-starburst-final.png") center
        center / contain no-repeat;
    }
  }

  .back-to-overview {
    height: 4rem;
    display: block;
    margin: -140px auto 0 auto;

    &--image {
      background: url("~@/assets/images/backtooverview.png") center center /
        contain no-repeat;
    }
  }
}
</style>

QuestCompleteView.vue

<template>
  <div class="quest-complete-view">
    <div class="reward reward--image"></div>

    <router-link to="quests">
      <div class="back-to-overview back-to-overview--image"></div>
    </router-link>
  </div>
</template>

<script lang="ts">
import { Vue } from "vue-property-decorator";

export default class QuestComplete extends Vue {}
</script>

<style scoped lang="scss">
@import "~@/styles/variables";
.quest-complete-view {
  width: 100%;

  .reward {
    width: auto;
    height: 56rem;

    &--image {
      background: url("~@/assets/images/reward.png") center center / contain
        no-repeat;
    }
  }

  .back-to-overview {
    height: 4rem;
    display: block;
    margin: -140px auto 0 auto;

    &--image {
      background: url("~@/assets/images/backtooverview.png") center center /
        contain no-repeat;
    }
  }
}
</style>

Auth-guard

import store from "@/store/index";

export default (to: any, from: any, next: any) => {
  if (store.state.auth.user) {
    next();
  } else {
    next("/login");
  }
};

Часть кода в QuestDetailView.vue, которая направляет / завершает

public handleButtonClick(): void {
    if (this.quest.status === QuestStatus.UNCOMPLETED) {
      this.startQuest(this.quest.id).then(() => this.$router.push("/quests"));
    } else if (this.quest.status === QuestStatus.IN_PROGRESS) {
      this.stopQuest(this.quest.id).then(() => this.$router.push("/complete"));
    }
}

Итакнам нужно следующее: когда мы направляемся к маршруту / complete, он рендерит компонент Questcomplete, являющийся «QuestCompleteView»

Когда мы выполняем render.push («/ allCompleted»), мы переходим на маршрут allCompletedс правильным компонентом, являющимся QuestAllCompletedView

...