Полностью динамический vue-router - PullRequest
0 голосов
/ 10 января 2019

Мы создаем огромный веб-сайт на основе Vue и Nuxt с более чем 25 различными типами страниц, которые не могут быть сопоставлены со стандартной логикой /: id или / Overview /: slug, которая поставляется из коробки с Vue Router.

Поскольку слизняк не подходит, мы думаем о следующем решении:

  1. Страница посещений пользователя "/ this-is-a-theme-page"
  2. Сервер вызывает API, который возвращает pageType topicPage
  3. topicPage относится к пустой странице WpTopicPage
  4. Мы устанавливаем WpTopicPage в качестве нашего компонента в нашем экземпляре шаблона Vue Router

В коде это выглядит следующим образом:

export function createRouter() {
  return new Router({
    mode: 'history',
    routes: [
      // 1. User visits page "/this-is-a-topic-page"
      {
        name: 'wildcard',
        path: '*',
        component: *, // this should be dynamic
        beforeEnter: (to, from, next) => {
          // 2. Server calls API that returns the pageType `topicPage`
          this.$axios.get(`/call-to-the-api?slug=${to.params.slug}`)
            .then((res) => {
              // 3. `topicPage` relates to the nuxt page `WpTopicPage`
              if(res.data.pageType === 'topicPage') {
                // 4. Set `WpTopicPage` as our Page component
                return WpTopicPage;
              }
            })
        },
      },
    ],
  });
}

Выше явно не работает. Есть ли способ динамически установить component в пределах маршрута в функции beforeEnter?

1 Ответ

0 голосов
/ 20 января 2019

Это возможно сделать. Я создал codepen для проверки:

Вот оно:

Vue.use(VueRouter);

let A = {
  mounted() {
    console.log('Mouted component A');
  },
};
let B = {
  mounted() {
    console.log('Mouted component B');
  },
};
let C = {
  mounted() {
    console.log('Mouted component C');
  },
};

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

app = new Vue({
  router,
  el: '#app',
  components: { A, B, C }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/3.0.2/vue-router.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <router-link :to="'/' + Math.random()">anything</router-link>
  <router-view></router-view>
</div>

Это вывод:

enter image description here

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

...