亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在加載組件之前等待 VueX 值加載

在加載組件之前等待 VueX 值加載

慕容森 2021-06-29 07:59:52
當用戶嘗試直接導航加載組件 url 時,我的 vuex 操作中會進行一個 http 調用,一旦它解析,它將在我的狀態中定義一個值。在解析 http 調用并定義狀態值之前,我不想加載我的組件。例如,在我的組件中export default {  computed: {    ...mapState({      // ** this value needs to load before component mounted() runs **      asyncListValues: state => state.asyncListValues    })  },  mounted () {    // ** I need asyncListValues to be defined before this runs **    this.asyncListValues.forEach((val) => {       // do stuff    });  }}asyncListValues在加載我的組件之前,如何讓我的組件等待加載?
查看完整描述

3 回答

?
慕村9548890

TA貢獻1884條經驗 獲得超4個贊

這樣做的方法是存儲狀態值。


例如,如果您的商店依賴于單個 API,您將執行以下操作。但是,對于多個 API,最好單獨存儲每個 api 加載狀態,或者為每個 API 使用一個專用對象。


通常你可以擁有 4 種狀態,我更喜歡在全局可訪問模塊中擁有它們:


// enums.js

export default {

  INIT: 0,

  LOADING: 1,

  ERROR: 2,

  LOADED: 3

};

然后,您可以將變量存儲在 vuex 狀態中,其中 apiState 使用INIT. 您也可以使用 初始化數組[],但這不是必需的。


import ENUM from "@/enums";

// store.js

export default new Vuex.Store({

  state: {

    apiState: ENUM.INIT,

    accounts: [],

    // ...other state

  },

  mutations: {

    updateAccounts (state, accounts) {

      state.accounts = accounts;

      state.apiState = ENUM.LOADED;

    },

    setApiState (state, apiState) {

      state.apiState = apiState;

    },

  },

  actions: {

    loadAccounts ({commit) {

      commit('setApiState', ENUM.ERROR);

      somFetchInterface()

        .then(data=>commit('updateAccounts', data))

        .catch(err=>commit('setApiState', ENUM.ERROR))

    }

  }

});

然后,通過添加一些computeds,您可以切換顯示哪個組件。這顯示了使用狀態的好處,因為您可以輕松識別錯誤狀態,并在狀態未準備好時顯示加載動畫。


<template>

  <ChildComponent v-if="apiStateLoaded"/>

  <Loader v-if="apiStateLoading"/>

  <Error v-if="apiStateError"/>

</template>

<script>

import ENUM from "@/enums";

export default {

  computed: {

    ...mapState({

      apiState: state=> state.apiState

    }),

    apiStateLoaded() {

      return this.apiState === ENUM.LOADED;

    },

    apiStateLoading() {

      return this.apiState === ENUM.LOADING || this.apiState === ENUM.INIT;

    },

    apiStateError() {

      return this.apiState === ENUM.ERROR;

    },

  })

}

</script>

或者,如果您只是asyncListValues使用空數組在 store 中初始化[],則可以避免期望數組的錯誤。


查看完整回答
反對 回復 2021-07-01
?
ibeautiful

TA貢獻1993條經驗 獲得超6個贊

由于您vue-router在問題中提到過,您可以使用beforeRouteEnterwhich 來推遲組件的渲染。


例如,如果您有一條名為“photo”的路線:


import Photo from "../page/Photo.vue";


new VueRouter({

  mode: "history",

  routes: [

    { name: "home", path: "/", component: Home },

    { name: "photo", path: "/photo", component: Photo }

  ]

});

你可以這樣使用beforeRouteEnter:


<template>

  <div>

    Photo rendered here

  </div>

</template>

<script>

export default {

  beforeRouteEnter: async function(to, from, next) {

    try {

      await this.$store.dispatch("longRuningHttpCall");


      next();

    } catch(exception) {

      next(exception);

    }

  }

}

</script>

它的作用是,等待操作完成,根據需要更新您的狀態,然后調用next()將告訴路由器繼續該過程(在 中渲染組件<router-view></router-view>)。


告訴我您是否需要 ES6-less 示例(例如,如果您不使用此語法)。


您可以查看此頁面上的官方文檔beforeRouteEnter,您還會發現您也可以使用beforeEnter.


查看完整回答
反對 回復 2021-07-01
?
侃侃爾雅

TA貢獻1801條經驗 獲得超16個贊

一種方法是將您的組件拆分為兩個不同的組件。一旦數據準備好,您的新父組件可以處理獲取數據并呈現子組件。


父組件.vue


<template>

  <child-component v-if="asyncListValues && asyncListValues.length" :asyncListValues="asyncListValues"/>

  <div v-else>Placeholder</div>

</template>

<script>

export default {

  computed: {

    ...mapState({

      asyncListValues: state => state.asyncListValues

    })

  }

}

</script>

子組件.vue


export default {

  props: ["asyncListValues"],

  mounted () {

    this.asyncListValues.forEach((val) => { 

      // do stuff

    });

  }

}


查看完整回答
反對 回復 2021-07-01
  • 3 回答
  • 0 關注
  • 297 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號