【问题标题】:Load routes from api in vue从 api 在 vue 中加载路由
【发布时间】:2019-04-07 12:32:06
【问题描述】:

我正在尝试通过我的 API 在 Vue 应用程序中加载路由。我尝试将数据推送到路由变量并使用 addRoutes 方法。但没有运气。我认为异步可能存在问题。但是为什么 addRoutes() 不起作用?

这是我的代码:

import Vue from 'vue';
import VueRouter from 'vue-router';
import axios from 'axios';

/**
 * Routes
*/
import item_index from '../../app/Tenant/Item/Views/Index.vue';
import contact_index from '../../app/Tenant/Contact/Views/Index.vue';
import eav_index from '../../app/Tenant/Eav/Views/create.vue';
import eav_create from '../../app/Tenant/Eav/Views/create.vue';

var routes = [
     { path: '/items', component: item_index, name: 'item_index' },
     { path: '/contact', component: eav_index , name: 'contact_index' , props: { entity_type_id: 1 }},
 ];


Vue.use(VueRouter);

const router = new VueRouter({
    mode: 'history',
    linkActiveClass: 'active',
    routes
});

axios
    .get('http://c1.fmt.dev/api/eav/entity_types')
    .then(response => {
        for (var i = 0; i < response.data.length; i++) {
            var type = response.data[i];
            var route = {
                path: '/' + type.name,
                component: eav_index,
                name: type.name + '_index',
                props: {
                    entity_type_id: type.id
                },
            };

            router.addRoutes([route]);
            alert(router.options.routes);
            // alert(JSON.stringify(routes));
        }
    })
    .catch(error => {
        console.log(error)
});

new Vue({
    el: '.v-app',
    data(){
      return {
        page_header: '',
        page_header_small: '',
      }
    },
    router, axios
});

【问题讨论】:

    标签: vue.js axios vue-component vue-router


    【解决方案1】:

    试试这个改进的代码。无需推迟 Vue 实例创建,因此无需延迟页面交互:

    import Vue from 'vue'
    import VueRouter from 'vue-router'
    import axios from 'axios'
    
    import item_index from '../../app/Tenant/Item/Views/Index.vue'
    import contact_index from '../../app/Tenant/Contact/Views/Index.vue'
    import eav_index from '../../app/Tenant/Eav/Views/create.vue'
    import eav_create from '../../app/Tenant/Eav/Views/create.vue'
    
    Vue.use(VueRouter)
    
    const router = new VueRouter({
      mode: 'history',
      linkActiveClass: 'active',
    
      routes: [{
        path: '/items',
        component: item_index,
        name: 'item_index'
      }, {
        path: '/contact',
        component: eav_index ,
        name: 'contact_index' ,
        props: {entity_type_id: 1}
      }]
    })
    
    new Vue({
      el: '.v-app',
      router,
    
      data () {
        return {
          page_header: '',
          page_header_small: '',
        }
      },
    
      methods: {
        getDynamicRoutes (url) {
          axios
            .get(url)
            .then(this.processData)
            .catch(err => console.log(err))
        },
    
        processData: ({data}) => {
          data.forEach(this.createAndAppendRoute)
        },
    
        createAndAppendRoute: route => {
          let newRoute = {
            path: `/${route.name}`,
            component: eav_index,
            name: `${route.name}_index`,
            props: {entity_type_id: route.id}
          }
    
          this.$router.addRoutes([newRoute])
        }
      },
    
      created () {
        this.getDynamicRoutes('http://c1.fmt.dev/api/eav/entity_types')
      }
    })
    

    为了更好的代码结构和可读性,将路由器定义移动到单独的文件中:

    在您的主文件中,只留下以下代码:

    // main.js
    import Vue from 'vue'   
    import router from '@/router'
    import axios from 'axios'
    
    new Vue({
      el: '.v-app',
      router,
    
      data () {
        return {
          page_header: '',
          page_header_small: '',
        }
      },
    
      methods: {
        getDynamicRoutes (url) {
          axios
            .get(url)
            .then(this.processData)
            .catch(err => console.log(err))
        },
    
        processData: ({data}) => {
          data.forEach(this.createAndAppendRoute)
        },
    
        createAndAppendRoute: route => {
          let newRoute = {
            path: `/${route.name}`,
            component: eav_index,
            name: `${route.name}_index`,
            props: {entity_type_id: route.id}
          }
    
          this.$router.addRoutes([newRoute])
        }
      },
    
      created () {
        this.getDynamicRoutes('http://c1.fmt.dev/api/eav/entity_types')
      }
    })
    

    在与主文件相同的文件夹中,使用“index.js”创建子文件夹“router”:

    // router/index.js
    import Vue from 'vue'
    import VueRouter from 'vue-router'
    
    import item_index from '../../../app/Tenant/Item/Views/Index.vue'
    import contact_index from '../../../app/Tenant/Contact/Views/Index.vue'
    import eav_index from '../../../app/Tenant/Eav/Views/create.vue'
    import eav_create from '../../../app/Tenant/Eav/Views/create.vue'
    
    Vue.use(VueRouter)
    
    export default new VueRouter({
      mode: 'history',
      linkActiveClass: 'active',
    
      routes: [{
        path: '/items',
        component: item_index,
        name: 'item_index'
      }, {
        path: '/contact',
        component: eav_index ,
        name: 'contact_index' ,
        props: {entity_type_id: 1}
      }]
    })
    

    【讨论】:

    • 我们需要在 main.js 中导入组件吗?我看到你在main.js中的createAndAppendRoute方法中引用了组件eav_index
    • 嗯...是的,好像需要在main.js中导入eav_index
    • 很奇怪,但这个解决方案对我来说并不奏效,因为 this.$router 在我的 main.js 文件中未定义。任何想法为什么? :( 我在那里进口了路由器...
    • 但解决方案本身有效:我用一些硬代码检查了这一点。
    • 我删除了 createAndAppendRoute 中的箭头函数,并且路由器变得可访问,但现在我在 addRoutes 方法中收到一个错误,指出 argument type: {path: *, component, name: string} is not assignable to parameter type RouteConfig[]...
    【解决方案2】:

    当您尝试添加路由时,vue 实例已经启动(与此问题中的问题相同:How to use addroutes method in Vue-router?)。您可以在加载路由后推迟 vue 初始化:

    //imports and stuff...
    
    axios
        .get('http://c1.fmt.dev/api/eav/entity_types')
        .then(response => {
            for (var i = 0; i < response.data.length; i++) {
                var type = response.data[i];
                var route = {
                    path: '/' + type.name,
                    component: eav_index,
                    name: type.name + '_index',
                    props: {
                        entity_type_id: type.id
                    },
                };
    
                // extend routes array prior to router init
                routes.push(route);
            }
            // init router when all routes are known
            const router = new VueRouter({
                mode: 'history',
                linkActiveClass: 'active',
                routes
            });
    
            // init vuw instance when router is ready
            new Vue({
                el: '.v-app',
                data(){
                  return {
                    page_header: '',
                    page_header_small: '',
                  }
                },
                router, axios
            });
        })
        .catch(error => {
            console.log(error)
    });
    

    【讨论】:

      猜你喜欢
      • 2021-11-06
      • 2021-01-25
      • 2019-08-26
      • 1970-01-01
      • 2018-10-11
      • 1970-01-01
      • 2019-12-06
      • 2020-08-11
      • 2019-06-26
      相关资源
      最近更新 更多