загружать маршруты через компонент из внешнего API и добавлять их в роутер - PullRequest
4 голосов
/ 05 июня 2019

Я хотел бы загрузить свои маршруты из внешнего API. Некоторые пользователи могут не иметь прав доступа к модулю.

Итак, моя навигационная панель выполняет вызов API и возвращает все модули. Эти объекты модуля содержат путь к файлу представления.

Я пытался создать маленькую песочницу, чтобы воспроизвести проблему

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

Если вы откроете этот URL в своем браузере

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

Сначала вы получите следующую ошибку

URL / Первый не найден

, но после нажатия на Первый модуль на панели навигации, представление Первый должно быть визуализировано.

Я думаю, что проблема связана с тем, что страница еще не запустила событие создания навигации после загрузки, и поэтому страница модуля не найдена. После изменения URL-адреса маршрутизатора у компонента навигации было достаточно времени, чтобы добавить все необходимые маршруты к маршрутизатору.

Как я могу загрузить эти URL-адреса до того, как маршрутизатор приведет к первому маршруту и ​​ответит на ошибку 404?

1 Ответ

0 голосов
/ 10 июня 2019

Ключевой идеей здесь является асинхронная загрузка маршрутов, что означает, что вы должны отложить загрузку вашего SPA до этого времени. В вашем index.js или main.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 - инверсию зависимости и stateful + singleton природу маршрутизатора, то имеет смысл начать его с самого начала. Таким образом, все, что нужно маршрутизатору, должно быть доступно. Это означает, что компонент navbar не должен отвечать за вызов API. Вы должны вынуть это.
  • Другое возможное решение - использовать метод $router.addRoutes(). Но это не подходит для ваших нужд. Это не будет работать с учетом авторизации. Это не помешает навигации.
  • На философском уровне, когда вы используете SPA с маршрутизацией на стороне клиента, тогда маршрутизация на стороне клиента - это собственный источник правды. Разумно знать все маршруты заранее, и поэтому большинство маршрутизаторов разработаны с учетом этой идеи. Таким образом, подобное требование плохо подходит для этой парадигмы. Если вам нужно что-то подобное, то сервер должен обладать знаниями о клиентских маршрутах, и во время обновления страницы сервер должен решить, что делать: загрузить SPA или отклонить страницу 404/403. И если доступ разрешен, сервер должен внедрить данные маршрутизации в HTML-страницу, которая затем будет выбрана Vue.js на стороне браузера. Для этого существует множество сложных SSR - рендеринг на стороне сервера .

Альтернативная стратегия: использовать охрану

  1. Определите все маршруты заранее в вашем маршрутизаторе для всех возможных представлений всех пользователей.
  2. Определите охранников для каждого авторизованного маршрута. Все эти охранники будут решены асинхронно.
  3. Вместо загрузки данных маршрутизации из API используйте API для возврата Матрицы авторизации . Используйте этот ответ API в ваших охранниках маршрута, чтобы определить доступ.
  4. Чтобы запретить вызовы к одному и тому же API несколько раз, вы можете использовать какое-то кэширование, например, Proxy, Memoization, store и т. Д. Как правило, для пользователя Auth Matrix не будет меняться между вызовами.

Преимущество этого заключается в том, что при необходимости вы все равно можете частично загрузить приложение, что приведет к значительному взаимодействию с пользователем за счет сокращения времени взаимодействия пользователя с приложением.

...