У меня есть два разных представления, которые я хотел бы показать для одного и того же пути, в зависимости от того, находится ли токен в LocalStorage или нет. Я мог бы переместить логику непосредственно в само представление, но мне было любопытно узнать, есть ли к этому способ в маршрутизаторе.
Что-то типа:
export default new Router({
mode: "history",
base: process.env.BASE_URL,
routes: [
{
path: "/",
name: "home",
component: function() {
if (...) {
return ViewA
} else {
return ViewB
}
}
},
]
});
Я пробовал использовать приведенный выше код, но не работал. Приложение работает нормально, но ни одно из двух представлений не отображается.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Для этого можно использовать геттер, но вам нужно обязательно импортировать оба компонента:
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);
}
}
}
Я добавил в свой ответ некоторую дополнительную информацию, которая может быть полезной. В моих заметках написано «не могу найти документацию». Однако вы можете увидеть, как работает функция рендеринга, в ссылке SO. stackoverflow.com/a/50137354/3261560
Опять же, это один из тех случаев, когда «это работает», но не совсем то, что я обычно делал бы. Он дает прямой ответ на вопрос, но есть более правильный способ добиться желаемого результата. Мой ответ «работает», даже если это не лучшая практика.
В документации сказано, что компоненты могут быть обещаниями, но после выполнения обещания компонент кэшируется.
Раньше я отвечал на тот же вопрос, и вы его видите здесь.
Вот пример:
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 и импортировать его в свой маршрутизатор, чтобы это работало.
Решение в вопросе сработало бы, если бы вы вернули компонент как импорт.
Поправьте меня, если я ошибаюсь, но
componentsне может быть функциями / массивами и т. д. - толькоobject. Еслиcomponentsможет - это функции - можете ли вы предоставить ссылку на документ? Это мне тоже очень поможет, если это правда.