vuex初始化全局数据的时序问题

582 阅读1分钟

实践中的认识,文章仅供参考。

背景

登录系统之后,需要初始化一些全局数据,然后存到store里,在需要使用的时候直接从store里面获取即可

初始化数据的时机

登录成功进入系统,在layout组件中调用接口获取数据(layout组件是系统界面的基本布局,组件层级是: App -> Layout -> Pages,登录系统之后,所有的页面组件都是在其下的)

layout组件的 beforeCreate生命周期中调用接口,具体代码如下:

写在beforeCreate生命周期中主要是想提前初始化数据的开始时间,以免数据到达之后子组件获取不到store的数据,但是这样一写就发现了一点小问题,👇👇

<template>
  <div class="Main">
    <router-view></router-view>
  </div>
</template>

<script>
  import { mapActions } from "vuex";
  export default {
    name: 'Main',
    props: {},
    components: {},
    data() {
      return {}
    },
    computed: {},
    watch: {},
    // INIT STORE
    async beforeCreate() {
      // 获取所有产品分类
      await this.$store.dispatch('product/getAllCatagory');

      // ⚠ mapActions执行在beforeCreated之后,
      // 在beforeCreated里不能直接调用通过mapActions映射的函数,必须写dispatch
      // await this.initStore()
    },
    created() { },
    mounted() { },
    methods: {
      ...mapActions('product', ['getAllCatagory']),
      async initStore() {
        await this.getAllCatagory()
      }
    },
    updated() { },
    beforeDestroy() { }
  }
</script>

<style lang='less' rel='stylesheet/less' scoped>
  .Main {
    position: absolute;
    width: 100%;
    height: 100%;
    overflow-y: auto;
  }
</style>

存在的问题

  1. mapActions执行在beforeCreated之后

  2. beforeCreated里不能直接调用通过mapActions映射的函数,必须写dispatch

  3. 事实上,子组件里的接口调用并不会因为layout组件里写了 async await就在其后执行,子组件加载的时候存在获取不到store的情况,我们可以在子组件里面增加computed来处理需要的store数据


优化补充—控制组件加载

如果存在一些需要提前初始化的数据,为了避免出现数据加载的时序问题,可以采取控制路由加载的方式处理,即控制子组件的加载,如下:

<router-view v-if="beReady"></router-view>

具体使用如下:

<template>
  <div class="Main">
    <router-view v-if="beReady"></router-view>
  </div>
</template>

<script>
  import { mapActions } from "vuex";
  export default {
    name: 'Main',
    props: {},
    components: {},
    data() {
      return {
        beReady: false,
      }
    },
    computed: {},
    watch: {},
    // INIT STORE
    async beforeCreate() {
      // 获取所有产品分类
      await this.$store.dispatch('product/getAllCatagory');

      // ⚠ mapActions执行在beforeCreated之后,
      // 在beforeCreated里不能直接调用通过mapActions映射的函数,必须写dispatch
      // await this.initStore()
    },
    created() { },
    mounted() { },
    methods: {
      ...mapActions('product', ['getAllCatagory']),
      async initStore() {
        await this.getAllCatagory()
        this.beReady = true
      }
    },
    updated() { },
    beforeDestroy() { }
  }
</script>

<style lang='less' rel='stylesheet/less' scoped>
  .Main {
    position: absolute;
    width: 100%;
    height: 100%;
    overflow-y: auto;
  }
</style>

我是 甜点cc,个人网站: blog.i-xiao.space/

回头看,轻舟已过万重山;向前看,前路漫漫亦灿灿。

公众号:【看见另一种可能】