MST

星途 面试题库

面试题:Vue异步组件加载状态下,如何优雅地处理不同加载阶段的UI展示

在一个包含多个异步组件的Vue应用中,每个异步组件有加载中、加载成功、加载失败等不同状态,如何通过统一且优雅的方式管理这些状态,并根据不同状态展示对应的UI?阐述你的设计思路并给出关键代码示例。
49.3万 热度难度
前端开发Vue

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 使用 Vuex 管理状态:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,便于统一管理异步组件的加载状态。
  2. 定义状态类型:在 Vuex 的 state 中为每个异步组件定义相应的状态字段,如 loading(加载中)、loaded(加载成功)、error(加载失败)。
  3. 创建 mutation 和 action:通过 mutation 来修改状态,action 用于触发异步操作并调用 mutation。例如,在异步组件开始加载时,触发一个 action 来修改 loading 状态为 true;加载成功时,修改 loaded 状态为 trueloading 状态为 false;加载失败时,修改 error 状态为 trueloading 状态为 false
  4. 组件中使用状态:在异步组件中通过计算属性获取 Vuex 中的状态,并根据不同状态展示相应的 UI。

关键代码示例

  1. Vuex 配置
// store.js
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    asyncComponent1: {
      loading: false,
      loaded: false,
      error: false
    },
    asyncComponent2: {
      loading: false,
      loaded: false,
      error: false
    }
    // 以此类推,为每个异步组件定义状态
  },
  mutations: {
    SET_LOADING(state, componentName) {
      state[componentName].loading = true;
      state[componentName].loaded = false;
      state[componentName].error = false;
    },
    SET_LOADED(state, componentName) {
      state[componentName].loading = false;
      state[componentName].loaded = true;
      state[componentName].error = false;
    },
    SET_ERROR(state, componentName) {
      state[componentName].loading = false;
      state[componentName].loaded = false;
      state[componentName].error = true;
    }
  },
  actions: {
    async loadAsyncComponent({ commit }, componentName) {
      commit('SET_LOADING', componentName);
      try {
        // 模拟异步操作
        await new Promise((resolve) => setTimeout(resolve, 1000));
        commit('SET_LOADED', componentName);
      } catch (error) {
        commit('SET_ERROR', componentName);
      }
    }
  }
});

export default store;
  1. 异步组件示例
<template>
  <div>
    <div v-if="$store.state.asyncComponent1.loading">加载中...</div>
    <div v-if="$store.state.asyncComponent1.loaded">加载成功</div>
    <div v-if="$store.state.asyncComponent1.error">加载失败</div>
    <button @click="$store.dispatch('loadAsyncComponent', 'asyncComponent1')">加载组件</button>
  </div>
</template>

<script>
export default {
  name: 'AsyncComponent1'
};
</script>

这样就可以通过 Vuex 统一管理多个异步组件的状态,并根据不同状态展示对应的 UI。