Vuex:子组件等待父组件分派操作

时间:2019-03-19 14:12:17

标签: vue.js action vuex getter

父组件(仪表板):

<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>

在仪表板组件(父级)中,我通过vuex操作dispatch('user/getUser)来获取用户数据,然后获取该用户dispatch('project/getProject)的项目。

在我的概述组件(子组件)中,我想显示该用户的项目信息。我称自己为mapGetters,并且在runningprojects中有一个组件变量data()。在我的mounted()生命周期中,我想将数据从我的吸气剂推入该数据数组。

出现以下问题:

刷新我的应用程序时,子组件console.log中的mounted()在父组件(仪表板)中的分发作业完成之前被调用。

仅当更改本地文件中的内容并且vue-cli进行实时重新加载时,该方法才有效。

chrome dev tools

1 个答案:

答案 0 :(得分:2)

由于vue应用的页面lifecycle。在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,只要状态发生变化,就会调用该函数。