ソース:nobiki/vue-test
RailsのTurbolinksを使いたくなかったのでフロントエンドで完結出来るようにvueやvue-routerなどを使ってみた
環境
anyenv
ndenv
webpack
bulma (こちら のテンプレートを借りてます)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 $ ndenv version v8.1.0 (set by /workspace/vue-test/.node-version) $ npm ls --depth=0 /workspace/vue-test ├── css-loader@0.28.9 ├── extract-text-webpack-plugin@3.0.2 ├── style-loader@0.20.1 ├── vue@2.5.13 ├── vue-loader@14.1.1 ├── vue-router@3.0.1 ├── vue-template-compiler@2.5.13 ├── vuex@3.0.1 └── webpack@3.10.0
Webpackに関して:WebpackでcssとjsをBundleしたメモ
サイトマップ トップページに3つリンクがあるだけの、とりあえずシンプルなやつです
1 2 3 4 トップ ├── ページ1 ├── ページ2 └── ページ3
Webpack: 設定とファイルツリー rules
に、vue-loaderの設定を追加 、resolve.alias
に、vue,vuex,vue-routerの設定を追加 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 $ cat /workspace/vue-test/webpack.config.js var ExtractTextPlugin = require("extract-text-webpack-plugin"); var path = require('path'); var webpack = require('webpack'); module.exports = { entry: { "common": path.join(__dirname, "./webpack/common/entry.js"), "app/top": path.join(__dirname, "./webpack/app/top/entry.js"), }, output: { filename: "./public/assets/[name]/bundle.js" }, module: { rules: [ { test: /\.vue$/, loader: 'vue-loader', }, { test: /\.css$/, loader: ExtractTextPlugin.extract({fallback:'style-loader',use:'css-loader'}) }, { test: /\.(jpg|gif|png|woff|woff2|eot|ttf|svg)$/, loader: 'url-loader?limit=100000' }, ] }, resolve: { alias: { 'vue': 'vue/dist/vue.esm.js', 'vuex': 'vuex/dist/vuex.esm.js', 'vue-router': 'vue-router/dist/vue-router.esm.js' } }, plugins: [ new ExtractTextPlugin("./public/assets/[name]/bundle.css") ] };
webpack関係の物は「webpack」ディレクトリに入ってます
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 $ tree /workspace/vue-test/webpack/ /workspace/vue-test/webpack/ ├── app │ └── top │ ├── components │ │ ├── index.vue │ │ ├── linkA.vue │ │ ├── linkB.vue │ │ └── linkC.vue │ ├── css │ │ └── top.css │ ├── entry.js │ ├── js │ │ └── top.js │ ├── router │ │ └── routes.js │ └── view │ ├── indexView.vue │ ├── linkAView.vue │ ├── linkBView.vue │ └── linkCView.vue └── common // →「common」ディレクトリ内はbulma関係のファイルなのでVueとは無関係
Vue: Router URLとViewを紐づけるやつ
1 2 3 4 5 6 7 8 9 10 11 12 $ cat /workspace/vue-test/webpack/app/top/router/routes.js import indexView from './../view/indexView.vue'; import linkAView from './../view/linkAView.vue'; import linkBView from './../view/linkBView.vue'; import linkCView from './../view/linkCView.vue'; export default [ { path: '/', component: indexView }, { path: '/linkA', component: linkAView }, { path: '/linkB', component: linkBView }, { path: '/linkC', component: linkCView }, ];
Vue: View h2タグが1つあるだけのシンプルなやつです
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 $ cat /workspace/vue-test/webpack/app/top/view/linkAView.vue <template> <div class="wrap linkA"> <h2>linkA</h2> </div> </template> <style scoped> .wrap { padding: 0 10px; } </style> <script> import linkA from './../components/linkA.vue'; export default { components: { linkA }, } </script>
Vue: Component 今回は画面遷移を確認するだけなので内容は何も無いよう
1 2 3 4 5 6 7 8 9 $ cat /workspace/vue-test/webpack/app/top/view/linkAView.vue <template> <div> </div> </template> <script> export default { methods: {} } </script>
Vue: top.js el
の行で、*[data-route]
を指定したら一括でrouter設定できるかなと思ってやってみたけどダメだったので3つ書いてるけどほかによい方法があるかもしれない(今回はなるべく掘り下げずシンプルに)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 import Vue from 'vue'; import Vuex from 'vuex'; import VueRouter from 'vue-router'; import routes from '../router/routes.js'; Vue.use(Vuex); Vue.use(VueRouter); const router = new VueRouter({ routes }); new Vue({ el: "*[data-route='contents']", router: router, }); new Vue({ el: "*[data-route='topNav']", router: router, }); new Vue({ el: "*[data-route='footNav']", router: router, });
Webpack: bundle 1 $ ./node_modules/.bin/webpack -p
HTML: index.html 長いので必要な部分だけ抜粋してます
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 <!DOCTYPE html> <html lang="ja"> <head> <link rel="stylesheet" type="text/css" href="/assets/common/bundle.css"> <link rel="stylesheet" type="text/css" href="/assets/app/top/bundle.css"> </head> <body> <nav class="navbar is-white topNav"> <div class="container"> <div class="navbar-menu" data-route="topNav"> <div class="navbar-start"> <router-link class="navbar-item" to="/">トップ</router-link> <router-link class="navbar-item" to="/linkA">リンクA</router-link> <router-link class="navbar-item" to="/linkB">リンクB</router-link> <router-link class="navbar-item" to="/linkC">リンクC</router-link> </div> </div> </div> </nav> <section class="container"> <div class="columns"> <div class="column is-10"> <div id="contents" class="box tile content" data-route="contents"> <router-view></router-view> </div> </div> </div> </section> <footer class="footer"> <div class="container"> <hr> <div class="content has-text-centered" data-route="footNav"> <p> <router-link to="/">トップ</router-link> | <router-link to="/linkA">リンクA</router-link> | <router-link to="/linkB">リンクB</router-link> | <router-link to="/linkC">リンクC</router-link> </p> </div> </div> </footer> <script async type="text/javascript" src="/assets/common/bundle.js"></script> <script async type="text/javascript" src="/assets/app/top/bundle.js"></script> </body> </html>
<router-link to="[リンク先]>
は、DOMがロードされた時にはaタグになります
<router-view>
に、リンク先の内容が出力されます