はじめに
現在開発しているアプリにてvue routerにてルート定義を動的(サーバーから取得)に定義する方法を検討しました。
環境
- vue: 2.5.17
- vue-router: 3.0.1
- vue-cli 3.0.1
手順
基本的なアプリの生成方法は割愛しますがvue-cliを利用しています。
1. router.jsの生成
ここではベースのルート定義だけを行います。
router.js
Vue.use(Router);
const router = new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/',
name: 'home',
component: Home
}
]
});
2. main.js
main.jsにて1で定義したrouterをセットします。
ここでは特別な設定はしていません。
main.js
import Vue from 'vue';
import App from './App.vue';
import router from './router';
new Vue({
el: '#app',
router,
components: {App},
template: '<App/>'
});
3. App.vue
App.vueにて動的にルート定義を行います。
componentはdynamic importで取り込んでいます。
/* webpackChunkName: "views_" */の部分は生成されるjsファイルのプレフィックスになります。
また、@/views/${v.vueName}.vue
の部分は全て変数にしてしまうとwebpackが認識できませんので、一部をパスにする必要があります。
App.vue
<template>
<div class="home">
<router-view/>
... some contents (router-link)
</div>
</template>
<script>
import Vue from 'vue';
import axios from 'axios';
export default Vue.extend({
name: 'app',
created() {
const routes = [];
// サーバーからルート定義を取得(axios使用)
axios.get('/routes').then(function(res) {
// dataは配列型のルート定義データを想定
res.data.forEach(function(v){
routes.push({
path: v.path,
name: v.name,
query: v.query,
// dynamic import
component: ()=> import(/* webpackChunkName: "views_" */ `@/views/${v.vueName}.vue`)
});
});
this.$router.addRoutes(routes);
}).catch(function(error) {
console.log('ERROR');
});
},
...
});
</script>
swaggerなんかと連携できれば面白いかもしれません。
以上です。
終わりに
私自身webpackについてはまだまだ勉強中ですので、ご指摘などありましたら幸いです。