Условный маршрут в Vue.js

У меня есть два разных представления, которые я хотел бы показать для одного и того же пути, в зависимости от того, находится ли токен в LocalStorage или нет. Я мог бы переместить логику непосредственно в само представление, но мне было любопытно узнать, есть ли к этому способ в маршрутизаторе.

Что-то типа:

export default new Router({
  mode: "history",
  base: process.env.BASE_URL,
  routes: [
    {
      path: "/",
      name: "home",
      component: function() {
        if (...) {
          return ViewA
        } else {
          return ViewB
        }
      }
    },
  ]
});

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

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
6
0
10 173
3

Ответы 3

Для этого можно использовать геттер, но вам нужно обязательно импортировать оба компонента:

import ViewA from '@/views/ViewA'
import ViewB from '@/views/ViewB'

export default new Router({
    mode: "history",
    base: process.env.BASE_URL,
    routes: [
        {
            path: "/",
            name: "home",
            get component() {
                if (...) {
                    return ViewA;
                } else {
                    return ViewB;
                }
            }
        },
    ]
});

В своих заметках я написал «не могу найти документацию по этому поводу», относящуюся к вышеизложенному. Хотя это не связано конкретно с этим, может быть полезно просмотреть некоторую информацию из https://stackoverflow.com/a/50137354/3261560, касающуюся функции рендеринга. Я изменил то, что там обсуждается, используя ваш пример выше.

component: {
    render(c) {
        if (...) {
            return c(ViewA);
        } else {
            return c(ViewB);
        }
    }
}

Поправьте меня, если я ошибаюсь, но components не может быть функциями / массивами и т. д. - только object. Если componentsможет - это функции - можете ли вы предоставить ссылку на документ? Это мне тоже очень поможет, если это правда.

AndrewShmig 09.02.2019 22:56

Я добавил в свой ответ некоторую дополнительную информацию, которая может быть полезной. В моих заметках написано «не могу найти документацию». Однако вы можете увидеть, как работает функция рендеринга, в ссылке SO. stackoverflow.com/a/50137354/3261560

John Shipp 09.02.2019 23:51

Опять же, это один из тех случаев, когда «это работает», но не совсем то, что я обычно делал бы. Он дает прямой ответ на вопрос, но есть более правильный способ добиться желаемого результата. Мой ответ «работает», даже если это не лучшая практика.

John Shipp 10.02.2019 00:04

В документации сказано, что компоненты могут быть обещаниями, но после выполнения обещания компонент кэшируется.

arivero 29.04.2021 18:02

Раньше я отвечал на тот же вопрос, и вы его видите здесь.

Вот пример:

routes: [
    {
      path: '*',
      beforeEnter(to, from, next) {
        let components = {
          default: [A, B, C][Math.floor(Math.random() * 100) % 3],
        };
        to.matched[0].components = components;

        next();
      }
    },

... где A, B, C - компоненты, и они выбираются случайным образом при каждом изменении маршрута. Итак, в вашем случае вы можете просто изменить логику beforeEnter в соответствии с вашими потребностями и установить любой компонент, который вы хотите, перед маршрутизацией к нему.

Хорошо, я нашел простой способ сделать это, используя функцию отложенной загрузки webpack в маршрутизаторе vue со свойством состояния хранилища vuex;

{
  path: '/',
  component: () => { 
    if (store.state.domain) {
      return import(/* webpackChunkName: "app-home" */ '../views/AppHome.vue');
    } else {
      return import(/* webpackChunkName: "home" */ '../views/Home.vue');
    }
  }
},

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

Решение в вопросе сработало бы, если бы вы вернули компонент как импорт.

Другие вопросы по теме