前回の記事
http://qiita.com/Satachito/items/7c393513bf42ea3d1ebd
で、vue を単一の HTML で見てきました。
今回は vue-cli を使用して、アプリのボイラーブレートらしく仕立ててみます。
バックエンドは MongoDB のビルトイン REST インターフェースを使ってみます。
http://qiita.com/Satachito/items/ec7b8cad2bf88b4c21fb
最終形はここにおいてあります。
https://github.com/Satachito/vue-sample
テンプレートのロード
vue-cli でアプリを作っていきます。
$ vue init webpack-simple bp
いくつか質問されます。
? Project name bp
? Project description A Vue.js project
? Author XXXXXX
? Use sass? No
上のように答えたとして、進めていきます。
bp の下に移動して、
npm i
npm run dev
として、動作確認しましょう。
bp の下の以下の3つのファイルをとりあえず使っていきます。(他にもありますが、とりあえず無視してください。)
index.html
src/main.js
config/index.js
vue のみ
import Vue from 'vue'
new Vue({
el: '#app'
, template: `<div>APP</div>`
})
ブラウザに APP と表示されます。
vue + vue-router
npm i vue-router --save
とモジュールをインストール。
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
new Vue({
el: '#app'
, router: new Router({
routes:
[ { path: '/sub', component: { template: '<div>SUB</div>' } }
, { path: '/', component: { template: '<div>HOME</div>' } }
]
})
, template: `
<div>
<router-link to='/'>Goto HOME</router-link>
<router-link to='/sub'>Goto SUB</router-link>
<router-view/>
</div>
`
})
vuex に行く前にお化粧
vue-material を使って上の vue + vue-router をアプリっぽくしてみます。
index.html で Material 用のフォントとアイコンを読むようにします。
<!DOCTYPE html>
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Roboto:300,400,500,700,400italic">
<link rel="stylesheet" href="//fonts.googleapis.com/icon?family=Material+Icons">
<div id="app"></div>
<script src="/dist/build.js"></script>
vue-material を npm でインストールします。
npm i vue-material --save
で、こんな感じ。
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
import 'vue-material/dist/vue-material.css'
import VueMaterial from 'vue-material'
Vue.use( VueMaterial )
new Vue({
el: '#app'
, router: new Router({
routes:
[ { path: '/sub', component: { template: '<div>SUB</div>' } }
, { path: '/', component: { template: '<div>HOME</div>' } }
]
})
, template: `
<div>
<md-toolbar>
<md-button class="md-icon-button" @click.native="$refs.sideNav.open()">
<md-icon>menu</md-icon>
</md-button>
<h2 class="md-title" style="flex: 1">Default</h2>
<md-button class="md-icon-button">
<md-icon>favorite</md-icon>
</md-button>
</md-toolbar>
<md-sidenav class="md-left" ref="sideNav">
<md-list>
<md-list-item @click.native="$refs.sideNav.close()"><router-link to='/'>Goto HOME</router-link></md-list-item>
<md-list-item @click.native="$refs.sideNav.close()"><router-link to='/sub'>Goto SUB</router-link></md-list-item>
</md-list>
</md-sidenav>
<router-view/>
</div>
`
})
テストデータにつなぐ
MongoDB のビルトイン REST インターフェースにつないでみます。
http://qiita.com/Satachito/items/ec7b8cad2bf88b4c21fb
今回アクセスしたい URL は localhost:28017/test/restaurants/ ですが、
直接 fetch すると same origin policy にひっかかってしまうため、
proxy を設定しなくてはなりません。
config/index.js の proxyTable を以下のように編集して、
/test 以下が localhost:28017 にフォワードされるようにします。
proxyTable: { '/test': { target: 'http://localhost:28017', changeOrigin: true } },
で、こんな感じ。
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
import 'vue-material/dist/vue-material.css'
import VueMaterial from 'vue-material'
Vue.use( VueMaterial )
new Vue({
el: '#app'
, data() { return { m: { rows: [] } } }
, router: new Router({
routes:
[ { path: '/detail/:idx', component: { template: '<h1>{{ $route.params.idx }}</h1>' } }
, { path: '/', component: { template: '<div>HOME</div>' } }
]
})
, created() {
fetch( '/test/restaurants/?limit=10' ).then(
p => p.json()
).then(
p => this.m = p
).catch(
err => alert( err )
)
}
, template: `
<div>
<md-toolbar>
<md-button class="md-icon-button" @click.native="$refs.sideNav.open()">
<md-icon>menu</md-icon>
</md-button>
<h2 class="md-title" style="flex: 1">Default</h2>
<md-button class="md-icon-button">
<md-icon>favorite</md-icon>
</md-button>
</md-toolbar>
<md-sidenav class="md-left" ref="sideNav">
<md-list>
<md-list-item v-for="( w, i ) in m.rows" :key="i">
<router-link :to="'/detail/' + i" @click.native="$refs.sideNav.close()">{{ i + ':' + w.name }}</router-link>
</md-list-item>
</md-list>
</md-sidenav>
<router-view/>
</div>
`
})
vue + vue-router + vuex
veux をインストール
npm i vuex --save
フェッチした JSON を表示するために、json-vue-er を npm でインストールします。
npm i json-vue-er --save
で、こんな感じ。
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
import Vuex from 'vuex'
Vue.use(Vuex)
import 'vue-material/dist/vue-material.css'
import VueMaterial from 'vue-material'
Vue.use( VueMaterial )
import JsonVueEr from "json-vue-er/JsonVueEr"
let
Detail = {
components: { JsonVueEr }
, template: `<json-vue-er :json="$store.state.json.rows[ $route.params.idx ]"></json-vue-er>`
}
let
Home = {
components: { JsonVueEr }
, template: `<json-vue-er :json="$store.state.json"></json-vue-er>`
}
new Vue({
el: '#app'
, store: new Vuex.Store({
state: { json: { rows: [] } }
, mutations: {
json: ( state, payload ) => state.json = payload.json
}
})
, router: new Router({
routes:
[ { path: '/detail/:idx', component: Detail }
, { path: '/', component: Home }
]
})
, created() {
fetch( '/test/restaurants/?limit=10' ).then(
p => p.json()
).then(
p => this.$store.commit( 'json', { json: p } )
).catch(
err => alert( err )
)
}
, template: `
<div>
<md-toolbar>
<md-button class="md-icon-button" @click.native="$refs.sideNav.open()">
<md-icon>menu</md-icon>
</md-button>
<h2 class="md-title" style="flex: 1">Default</h2>
<md-button class="md-icon-button">
<md-icon>favorite</md-icon>
</md-button>
</md-toolbar>
<md-sidenav class="md-left" ref="sideNav">
<md-list>
<md-list-item v-for="( w, i ) in $store.state.json.rows" :key="i">
<router-link :to="'/detail/' + i" @click.native="$refs.sideNav.close()">{{ i + ':' + w.name }}</router-link>
</md-list-item>
</md-list>
</md-sidenav>
<router-view/>
</div>
`
})
出来上がったものはここにおいてあります。