Как я могу динамически установить компонент назначения в маршрутизаторе Vue

Я пытаюсь динамически установить целевой компонент для маршрута vue-router.

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

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

router.beforeEach((to, from, next) => {
  get_data_from_server(to.fullPath).then(() => {
    // set the "to" component, but how?
    next();
})

Но, как говорится в комментарии, как бы я установил «компонент» - в объекте «кому» нет свойства компонента. (Похоже, что это находится в component.default.render, но это не задокументировано и не похоже, что с этим нужно связываться.)

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

Как создать маршрут к пункту назначения, который не известен во время сборки?


person bmacnaughton    schedule 01.04.2017    source источник
comment
Еще приключения: я обнаружил, что можно добавить маршрут github.com/vuejs/vue -маршрутизатор/коммит/   -  person bmacnaughton    schedule 02.04.2017


Ответы (1)


Кажется, это решение работает.

router.beforeEach((to, from, next) => {
  get_data_from_server(to.fullPath).then(component => {
    if (to.matched.length === 0) {
      // the target route doesn't exist yet
      router.addRoutes({path: to.path, component: component})
      next(to.fullPath)
      return
    } else {
      // the route and component are known and data is available
      next()
    }
})

Ключом было найти ссылку в моем комментарии выше, которая показывает фиксацию vue-router, которая реализует addRoutes().

Одна вещь, о которой следует помнить, это то, что новые маршруты добавляются в конце (имеет смысл), поэтому любые присутствующие подстановочные знаки могут привести к непреднамеренным совпадениям. У меня был общий маршрут, который перенаправлял на страницу по умолчанию. Но это совпало до вновь добавленного совпадения, потому что оно было раньше списка. И это вызвало переполнение стека. Фактически код после if (to.matched.length === 0) является маршрутом по умолчанию.

person bmacnaughton    schedule 02.04.2017
comment
Я был бы осторожен с запросом AJAX внутри защиты маршрута .beforeEach. Это может замедлить работу вашего приложения (или сделать его медленным). Одним из небольших улучшений было бы добавление оператора if ПЕРЕД вызовом get_data_from_server. Таким образом, вы получаете данные только в том случае, если маршрут еще не добавлен. - person Maurice; 02.04.2017
comment
Справедливый комментарий - содержимое целевой страницы, к сожалению, определяется в серверной системе управления кодом. Таким образом, целевому компоненту нужны данные с этой страницы независимо от того, был ли добавлен маршрут или нет. Но в соответствии с вашим предложением я упустил из виду, что код предотвращает дублирование вызова .beforeEach(), когда правильные данные уже присутствуют. - person bmacnaughton; 02.04.2017
comment
Я мог бы добавить кеширование в какой-то момент, и в этом случае имело бы смысл реструктурировать код в соответствии с вашим предложением. - person bmacnaughton; 02.04.2017