Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

vue-router 2, how to fetch routes via ajax?

How do I create the routes array dynamically, after fetching it via ajax?

Is there a way to add/push new routes to the router after it has been initialized?

This doesn't work:

new Vue({
  el: '#app',
  template: '<App/>',
  data: {
    content: []
  },
  created: function () {
    this.$http.get('dummyjsondatafornow').then((response) => {

      // this doesn't work when creating the VueRouter() outside the Vue instance, as in the docs.
      // this.$router.options.routes.push({ path: '/about', component: About })

      let routes = [
        { path: '/about', component: About }
      ]

      // this doesn't work either
      this.router = new VueRouter({
        routes: routes
      })
    })
  },
  // router: router,
  components: { App }
})
like image 348
Emin Avatar asked Nov 17 '16 16:11

Emin


2 Answers

I don't believe there is no.

That said you can wildcard the route so that may provide you with an alternative.

I built a site where the backend (and in turn pages created) were controlled via a CMS which served all pages to Vue as JSON. This meant Vue wasn't aware of the routes the backend was creating.

Instead we passed all the CMS pages to Vue Router via a single * wildcard component. In Vue Router 2 this would look like:

const routes = [
  { path: '*', component: AllPages }
]

Vue Router 2 allows for Advanced Matching Patterns

These allow you to set a wide variety of conditions, therefore whilst you can't inject the object passed back via ajax into your router you can add a dynamic component to an AllPages component that is wildcard matched. This would allow you to pass the name of the component to load via your ajax request and then load that component when the page is called. i.e.

Your Ajax response:

{
  // url: component name
  '/about/': 'about',
  '/about/contact/': 'contact',
  ...
}

Then in an AllPages vue component:

<template>
  <component v-bind:is="currentView"></component>
</template>

<script>

  module.exports = {
    data () {
      return {
        currentView: '',
        ajaxRoutes: {}, // loaded via ajax GET request
        ...
      }
    },
    // watch $route to detect page requests
    watch: {
      '$route' (to, from) {
        if (this.ajaxRoutes[to]) {
          this.currentView = this.ajaxRoutes[to]
        }
      }
    },
    ...
  }

</script>

The above is a rather abbreviated idea but essentially you dynamically load the component based on the path the user requested.

like image 121
GuyC Avatar answered Oct 23 '22 10:10

GuyC


I think this is fixed in version 2.3.0. You can now run

router.addRoutes(routes);

to dynamically add routes.

https://github.com/vuejs/vue-router/commit/0e0fac91ab9809254174d95c14592e8dc2e84d33

like image 22
billaraw Avatar answered Oct 23 '22 10:10

billaraw