通过组件从外部api加载路由并将其添加到路由器

时间:2019-06-05 09:14:35

标签: vue.js vue-router

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

因此,我的导航栏进行了API调用,并返回了所有模块。这些模块对象包含视图文件的路径。

我试图创建一个小沙盒来重现该问题

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

如果您在浏览器中打开此URL

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

您将首先遇到以下错误

  

找不到网址/第一个

,但是在导航栏中单击第一个模块链接后,应该呈现第一个视图。

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

如何在路由器通向第一条路由并响应404错误之前加载这些URL?

1 个答案:

答案 0 :(得分:0)

此处的主要思想是异步加载路由,这意味着您必须将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页面中注入路由数据,然后由浏览器端的Vue.js来选择路由数据。为此,存在许多复杂的 SSR-服务器端呈现技术。

替代策略:使用警卫

  1. 为所有用户的所有可能视图,在路由器中预先定义所有路由。
  2. 为每条授权路线定义后卫。所有这些保护措施都将异步解决。
  3. 代替从API加载路由数据,而使用API​​返回授权矩阵。在您的路由卫士中使用此API响应来确定访问权限。
  4. 为防止多次调用同一API,可以使用某种缓存,例如代理,备忘录,存储等。通常,对于用户而言,两次调用之间的身份验证矩阵不会有所不同。

为此,您仍然可以根据需要通过减少用户与应用程序交互的时间来部分加载应用程序,从而带来有意义的用户体验。