vue.js - 通过组件从外部 api 加载路由并将它们添加到路由器

标签 vue.js vue-router

我想从外部 API 加载我的路线。某些用户可能没有访问模块的权限。

所以我的导航栏进行 API 调用并获取返回的所有模块。这些模块对象包含 View 文件的路径。

我尝试创建一个小沙箱来重现该问题

https://codesandbox.io/s/vue-routing-example-i5z1h

如果您在浏览器中打开此网址

https://i5z1h.codesandbox.io/#/First

首先会报如下错误

Url /First not found

但是在点击导航栏中的第一个模块链接后,应该会呈现第一个 View 。

我认为问题与页面加载后还没有启动导航创建事件有关,因此找不到模块页面。更改路由器 URL 后,导航组件有足够的时间将所有必需的路由添加到路由器。

如何在路由器引导到第一个路由并响应 404 错误之前加载这些 URL?

最佳答案

这里的关键思想是异步加载路由,这意味着您必须将 SPA 的加载推迟到那个时候。在您的 index.jsmain.js 中,您的代码将如下所示:

// Some functions are assumed and not defined in the below code.
import Vue from 'vue';
import VueRouter from 'vue-router';

// Application root component
import App from './App.vue';
import { getRoutes } from './api';

// Register Vue plugins
Vue.use(VueRouter);


// Make API call here

// Some animation before the app is fully rendered.
showLoader();

getRoutes(/* Optional User data */)
  .then((routesData) => {
    // Stop the animation
    stopLoader();
    return routesData;
  })
  .then((routesData) => {

    // processRoutes returns an array of `RouteConfig`
    const routes = processRoutes(routesData);

    const router = new Router({
      routes: [
        ...routes,
        {
          path: '*',
          component: NotFound
        }
      ]
    });
  })
  .then((router) => {
    const app = new Vue({
      el: '#app',
      router,
      template: '<App/>',
      components: { App }
    });
  });

此外,您还需要做一些事情:

  • 路由通常是更高级别的关注点。所以如果你考虑 DIP - Dependency Inversion以及路由器的有状态+单例特性,那么在一开始就引导它是有意义的。因此,路由器需要的任何东西都应该可用。这意味着 navbar 组件不应该负责进行 API 调用。你必须把它拿出来。
  • 另一种可能的解决方案是使用$router.addRoutes() 方法。但它不足以满足您的需求。考虑到授权是行不通的。它不会阻止导航。
  • 在哲学层面上,当您将 SPA 与客户端路由一起使用时,客户端路由就是它自己的真理来源。预先知道所有路由是合理的,因此大多数路由器在设计时都考虑到了这个想法。因此,这样的要求不适合这种范式。如果您需要这样的东西,那么服务器应该了解客户端路由,并且在页面刷新期间,服务器应该决定要做什么——加载 SPA 或拒绝 404/403 页面。如果允许访问,服务器应该在 HTML 页面中注入(inject)路由数据,然后由浏览器端的 Vue.js 选择。许多复杂的SSR - 服务器端渲染技术都可以实现这一点。

替代策略:使用守卫

  1. 在路由器中为所有用户的所有可能 View 预先定义所有路由。
  2. 为每条授权路线定义守卫。所有这些守卫都将异步解决。
  3. 不是从 API 加载路由数据,而是使用 API 返回一个授权矩阵。在您的路由守卫中使用此 API 响应来确定访问权限。
  4. 要防止多次调用同一 API,您可以使用某种缓存,例如代理、内存、存储等。通常,对于用户而言,Auth Matrix 不会因调用而异.

这样做的一个优势是,如果需要,您仍然可以部分加载应用程序,从而减少用户与应用程序交互的时间,从而带来有意义的用户体验。

关于vue.js - 通过组件从外部 api 加载路由并将它们添加到路由器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56457536/

相关文章:

javascript - 将事件绑定(bind)到多个对象

vue.js - 重新加载时Vue路由器重定向到主页

javascript - Vue过渡动画不播放但保持其动画持续时间

vue.js - 是否可以在 vue 2 中使用没有组件的 vue-router?

javascript - 如何避免 Vue 路由器中的这种类型的路径冗余?

vue.js - 我们可以在 vuejs 的自定义组件模板中使用 v-for 吗?

javascript - Vue.js - 将变量附加到组件

javascript - Vue js 带条件的 for 循环

vue.js - Vue router2 没有捕获深层嵌套路由

javascript - JSON 数据中的 Vue v-links