Vuex: дочерний компонент ожидает действия родительского компонента - PullRequest
1 голос
/ 19 марта 2019

Родительский компонент (панель мониторинга):

<template>
<div id="dashboard">
  <Header />
  <b-container>
    <div>
      <b-row>
        <b-col>
          <Overview />
        </b-col>
      </b-row>
    </div>
  </b-container>
</div>
</template>

<script>
import Header from '@/components/common/Header';
import Overview from '@/components/dashboard/Overview';
import { mapGetters } from 'vuex';

export default {
  name: 'dashboard',
  components: {
    Header,
    Overview
  },
  mounted() {
    const sessionId = this.$cookie.get('connect.sid');
    this.$store.dispatch('user/getUser', sessionId).then((userData) => {
      this.$store.dispatch('project/getProject', userData.data.user);
    });
  },
  computed: {
    ...mapGetters('user', {
      user: 'getUser'
    })
  }
}
</script>

Дочерний компонент (обзор):

<template>
<div class="overview">
  <div class="overview__title">
    <h1>
      Welcome {{user.cn[0]}} // Works
    </h1>
  </div>
  <div class="overview__project">
    <p v-for="project in runningprojects" :key="project._id">
      {{project.name}} // Does not work at refresh
    </p>
  </div>
</div>
</template>

<script>
import {mapGetters} from 'vuex';
export default {
  name: 'dashboard-overview',
  data() {
    return {
      runningprojects: []
    }
  },
  computed: {
    ...mapGetters('user', {
      user: 'getUser'
    }),
    ...mapGetters('project', {
      projects: 'getProjects',
      allProjects: 'getAllProjects'
    })
  },
  mounted() {
    console.log("mounted this.projects", this.projects);
    // add something from this.projects to this.runningprojects
  },
  methods: {
    calcReq() {
      ...
    },
    ...
}
</script>

В моем компоненте панели мониторинга (parent) Я получаю данные пользователя с действием vuex dispatch('user/getUser), и после этого я выбираю проекты этого пользователя dispatch('project/getProject).

В моем компоненте Overview (дочернем) я хочу показать информацию о проекте этого пользователя.пользователь.Я называю мой mapGetters, и у меня есть переменная компонента runningprojects внутри data().В моем жизненном цикле mounted() я хочу отправить данные из моих геттеров в этот массив данных.

Дается следующая проблема:

Когда я обновляю свое приложение,console.log из моего дочернего компонента mounted() вызывается до завершения диспетчерских заданий в родительском компоненте (панель мониторинга).

Это работает, только если что-то изменить в моих локальных файлах, а vue-cli выполняет перезагрузку в реальном времени.

chrome dev tools

1 Ответ

2 голосов
/ 19 марта 2019

Из-за страницы lifecycle приложения vue.когда компонент рендерит mounted вызывается после created, и он не будет ждать вызовов ajax или любых async.

Одним из решений было бы не render child component до async возврата

<template>
<div id="dashboard">
  <Header />
  <b-container>
    <div>
      <b-row>
        <b-col>
          <Overview v-if="finished"/>
        </b-col>
      </b-row>
    </div>
  </b-container>
</div>
</template>

<script>
import Header from '@/components/common/Header';
import Overview from '@/components/dashboard/Overview';
import { mapGetters } from 'vuex';

export default {
  name: 'dashboard',
  data() {
    return {
      finished: false,
    }
  },
  components: {
    Header,
    Overview
  },
  mounted() {
    const sessionId = this.$cookie.get('connect.sid');
    this.$store.dispatch('user/getUser', sessionId).then((userData) => {
      this.$store.dispatch('project/getProject', userData.data.user);
      this.finished = true;
    });
  },
  computed: {
    ...mapGetters('user', {
      user: 'getUser'
    })
  }
}
</script>

Просто добавьте v-if в child component и когда dispatch имеет возвращаемое значение, тогда установите значение true, которое будет отображать child component, и тогда mounted будет иметь значения, которые вы хотите

Другое решение будет.

Используйте функцию updated вместо mounted, которая будет вызываться при каждом изменении состояния.

...