仅当视图中的所有组件均已获取其所需数据时,Vue路由器才能解决视图变更

wn9m85ua  于 2023-01-14  发布在  Vue.js
关注(0)|答案(1)|浏览(106)

在Vue中,我创建了完整的SFC组件,它们可以独立地获取、渲染数据并与数据交互。我只需将其作为一个 prop 传递给相应的API端点,CRUD逻辑始终保持不变。数据获取是使用onMountedonBeforeRouteChange激活的。
组件在收到后端回复之前是空的。我 * 可以 * 在获取数据时显示加载程序。但是,如果有多个组件具有加载动画和不同的加载时间,那么这是糟糕的UX,用户可能会困惑为什么视图不断变化。
因此,我希望仅在所有数据获取组件都发出某种就绪状态后才呈现完整的Router视图。
我知道您可以在导航保护中获取数据,例如beforeResolve,但是所有导航保护(afterEach除外)都在视图组件挂载之前激活,这意味着视图组件中的任何逻辑只有在可见时才开始发生。
我最好的情况是:
1.用户单击<RouterLink :to="nextView">
1.页面显示一个全局加载栏,视图不会更改

  1. nextView中的所有子组件都开始获取它们的数据。
    1.一旦nextView中的所有子组件都获取了它们的数据,视图就会呈现/更改
    1.加载条消失。
    我试过让所有的数据获取组件发出某种就绪状态,然后让视图组件修改全局存储以表示所有组件就绪后的就绪状态,然后我试着在beforeResolve导航保护中等待就绪状态,但是,同样,beforeResolve不会挂载组件,这意味着它永远不会接收到状态更改。
g9icjywg

g9icjywg1#

没有办法触发组件挂载钩子,甚至在不挂载它的情况下设置它的状态。同样,你不能挂载下一个路由组件,同时保持渲染前一个路由组件。
我的建议是将一个集中式存储连接到每个子组件(您也可以只通过存储标识符独立地连接到它)。这样您就可以在安装组件之前填充存储,然后再连接到它。
现在,您只需要一种方法来告诉路由器守卫在导航到特定路由之前要填充哪个存储。我建议在路由元数据中设置此信息,例如,创建一个VUEX名称空间数组,在该数组上应该触发特定的操作。

router.beforeEach(async (to, from, next) => {
  if (to.meta && to.meta.childStores) {
    // setting a loading flag in a global vuex module to trigger the loader
    store.commit("setLoading", true);
    // Dispatching the actions in each vuex module required for this route 
    for (let s of to.meta.childStores) {
      await store.dispatch(`${s}/fetchData`);
    }
    // disabling the loader after all requests have finished and proceeding to the next route
    store.commit("setLoading", false);
    next();
  }
  store.commit("setLoading", false);
  next();
});

您可以通过一个最小的工作示例来查看这个Codesandbox

相关问题