Vue.jsでSPA - [7] Vueからサーバデータ取得
前回のサーバへのAPIコールをVueの中に入れてく回.今回はスクリーンショットから
スクリーンショット
リアルデータでそれっぽく動くようになってきたでこれ
APIコールを入れたコード
長くなってきたがとりあえず貼り付ける.fetch
をつかうパターン.
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- import CSS -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!-- import Vue before Element -->
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<!-- 1. import Vue router -->
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<!-- import JavaScript -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/element-ui/2.4.1/locale/en.js"></script>
<link rel="stylesheet" href="../app.css">
</head>
<body>
<div id="app">
<el-container>
<el-header height="100px">
<img src="../static/img/placeholder-logo-2-300x167.png" height="100" align="left">
</el-header>
<el-container>
<el-aside width="200px">
<el-col :span="24">
<el-menu default-active="1" class="el-menu-vertical-demo">
<el-menu-item index="1">
<i class="el-icon-location"></i>
<!-- 6. When clicking, it loads the contents defined in 2 and 1 -->
<router-link to="/location"><span>Location</span></router-link>
</el-menu-item>
<el-menu-item index="2">
<i class="el-icon-document"></i>
<!-- 6. When clicking, it loads the contents defined in 2 and 1 -->
<router-link to="/foo"><span>foo</span></router-link>
</el-menu-item>
<el-menu-item index="3">
<i class="el-icon-setting"></i>
<!-- 6. When clicking, it loads the contents defined in 2 and 1 -->
<router-link to="/bar"><span>bar</span></router-link>
</el-menu-item>
</el-menu>
</el-col>
</el-aside>
<el-main>
<!-- 7. The contents will be load here -->
<router-view></router-view>
</el-main>
</el-container>
</el-container>
</div>
</body>
<script>
// 2. Define route components.
const Location = { template: '<location-table></location-table>' } // 9. Use the component here
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }
// 3. Define some routes
const routes = [
{ path: '/location', component: Location },
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar }
]
// 4. Create the router instance and pass the `routes` option
const router = new VueRouter({
routes // short for `routes: routes`
})
// 8. Define component
Vue.component('location-table', {
data: function() {
return {
location: [] // 10-1. location is now initialized as empty - get data from a server!
}
},
created: function() {
this.getLocation();
},
methods: {
getLocation: function(){ // 10-2. function for server API call
let url = 'your-api-endpoint-here';
fetch(url)
.then(response => response.json())
.then(json => {
this.location = json.data; // 10-3. Accessing data in [[PromiseValue]]
console.log(json.data);
})
.catch(error => console.error(error))
}
},
template: `
<el-table :data="location" style="width: 100%">
<el-table-column prop="id" label="id" width="100"></el-table-column>
<el-table-column prop="name" label="name"></el-table-column>
<el-table-column prop="country" label="country" width="180"></el-table-column>
<el-table-column prop="metro" label="metro" width="180"></el-table-column>
<el-table-column prop="market" label="market" width="180"></el-table-column>
<el-table-column prop="status" label="status" width="180"></el-table-column>
</el-table>
`
})
ELEMENT.locale(ELEMENT.lang.en)
var vm = new Vue({
// 5. Inject the router in the Vue instance
router,
el: '#app'
})
</script>
</html>
前回からの変更点
Vue.component
の10-1
10-2
10-3
のところ
-
10-1
はサーバから持ってくるので空にしておいて -
10-2
にデータ取ってくるメソッドgetLocation
を定義 -
10-3
でcreated
でインスタンスの準備ができたらgetLocation
をコールする
APIコールをどの時点(created
or mounted
)で行うかについてはこの考察が詳しかった:Vuejs APIアクセスはcreatedとmountedのどちらで行う?
長くなってきたのでファイル分ける
こんなんでいいのかようわからんけど,見にくくなってきたのでコンポーネントのところを分けることにする.おれおれな感じもするが,まあ一応テンプレートとロジック入ってる形で切り出せるし.やっぱり単一ファイルコンポーネント使いやすいようにvue-cli
でやっとくべきだったか...
メイン側
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- import CSS -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!-- import Vue before Element -->
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<!-- 1. import Vue router -->
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<!-- import JavaScript -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/element-ui/2.4.1/locale/en.js"></script>
<link rel="stylesheet" href="../../app.css">
</head>
<body>
<div id="app">
<el-container>
<el-header height="100px">
<img src="../../static/img/placeholder-logo-2-300x167.png" height="100" align="left">
</el-header>
<el-container>
<el-aside width="200px">
<el-col :span="24">
<el-menu default-active="1" class="el-menu-vertical-demo">
<el-menu-item index="1">
<i class="el-icon-location"></i>
<!-- 6. When clicking, it loads the contents defined in 2 and 1 -->
<router-link to="/location"><span>Location</span></router-link>
</el-menu-item>
<el-menu-item index="2">
<i class="el-icon-document"></i>
<!-- 6. When clicking, it loads the contents defined in 2 and 1 -->
<router-link to="/foo"><span>foo</span></router-link>
</el-menu-item>
<el-menu-item index="3">
<i class="el-icon-setting"></i>
<!-- 6. When clicking, it loads the contents defined in 2 and 1 -->
<router-link to="/bar"><span>bar</span></router-link>
</el-menu-item>
</el-menu>
</el-col>
</el-aside>
<el-main>
<!-- 7. The contents will be loaded here -->
<router-view></router-view>
</el-main>
</el-container>
</el-container>
</div>
</body>
<!-- 10. Load components -->
<script src="./location.js"></script>
<!-- Routing and main -->
<script>
// 2. Define route components.
const Location = { template: '<location-table></location-table>' } // 9. Use the component here
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }
// 3. Define some routes
const routes = [
{ path: '/location', component: Location },
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar }
]
// 4. Create the router instance and pass the `routes` option
const router = new VueRouter({
routes // short for `routes: routes`
})
ELEMENT.locale(ELEMENT.lang.en)
var vm = new Vue({
// 5. Inject the router in the Vue instance
router,
el: '#app'
})
</script>
</html>
コンポーネント側
location.js
Vue.component('location-table', {
data: function() {
return {
location: [] // 10-1. location is now initialized as empty - get data from a server!
}
},
created: function() {
this.getLocation();
},
methods: {
getLocation: function(){ // 10-2. function for server API call
let url = 'your-api-end-point-here';
fetch(url)
.then(response => response.json())
.then(json => {
this.location = json.data; // 10-3. Accessing data in [[PromiseValue]]
console.log(json.data);
})
.catch(error => console.error(error))
}
},
template: `
<el-table :data="location" style="width: 100%">
<el-table-column prop="id" label="id" width="100"></el-table-column>
<el-table-column prop="name" label="name"></el-table-column>
<el-table-column prop="country" label="country" width="180"></el-table-column>
<el-table-column prop="metro" label="metro" width="180"></el-table-column>
<el-table-column prop="market" label="market" width="180"></el-table-column>
<el-table-column prop="status" label="status" width="180"></el-table-column>
</el-table>
`
})
次回
これであとはコンポーネントを増やせばアプリっぽくなっていく感じになってきたので,次は
- コンポーネント増やしていくか
- このあたりでどこかクラウドにデプロイしてみるか(サーバレスな感じでやりたい)
- 1をやりながら
POST
系の動きを書くか
あたりをやってみるかな
シリーズ
- Vue.jsでSPA - [1] Element UIでベースの画面をつくる
- Vue.jsでSPA - [2] Element UIで各ペインの画面をつくる
- Vue.jsでSPA - [3] vue-routerでルーティング
- Vue.jsでSPA - [4] コンポーネントにしてみる
- Vue.jsでSPA - [5] リアクティブになってる?
- Vue.jsでSPA - [6] サーバからのデータ取得
- Vue.jsでSPA - [7] Vueからサーバデータ取得
- Vue.jsでSPA - [8] バックエンドとうまくやっていこうとして試したこと
- Vue.jsでSPA - [9] 今更ながらCORSとそのエラーの回避方法
- Vue.jsでSPA - [10] Safari..お前か...3rd party cookie
- Vue.jsでSPA - [11] Element UIでログイン画面
- Vue.jsでSPA - [12] ログイン:シングルペインからツーペインへ画面遷移
- Vue.jsでSPA - [13] モバイル向けに OnsenUI に手をだす
- Vue.jsでSPA - [14] Vue.jsとOnsenUIを使ったオレオレなショッピングカートチュートリアル
- Vue.jsでSPA - [15] 世界中の人とミーティング時間を決める時に便利なやつ
- Vue.jsでSPA - [16] へー、FirebaseでWebアプリのログインってこうやるのか