åäžããŒãžã¢ããªã±ãŒã·ã§ã³ïŒSPAïŒã«ã¯ãé床ãæ¬åœã«åªããUXãHTMLããŒã¯ã¢ããã®å®å šãªå¶åŸ¡ãªã©ãå€ãã®å©ç¹ããããŸãã ãŸããŸãå€ãã®SPAãµã€ãããããŸãã SPAéçºããã»ã¹ãç°¡çŽ åããããŒã«ãå¢ããŠããŸãã è¥ããŠææãªVue.jsãã¬ãŒã ã¯ãŒã¯ã«ã€ããŠã¯ããã§ã«èªãã§ãããšæããŸãã Vueãããæ·±ãæãäžããå ·äœçãªäŸãæããŠãåçŽãªSPAãæ±ãããšããå§ãããŸãã
ç°¡åãªããã°ã®ã¯ã©ã€ã¢ã³ããµãŒããŒã¢ããªã±ãŒã·ã§ã³ãäœæããŸãã ã¢ããªã±ãŒã·ã§ã³ã¯ããšã³ããªã®ãªã¹ããšåã ã®ãšã³ããªã®å šæã衚瀺ããŸãã ãããŠãã¡ãããããã¯ãã¹ãŠããŒãžããªããŒãããªããŠãèµ·ãããŸãã
ãã®ã¢ããªã±ãŒã·ã§ã³ã®äŸãããç解ããåŸãVueã«ããŒã¿ãæœåºããã«ãŒããäœæããVueã®èå³æ·±ãæ©èœã§ããåäžãã¡ã€ã«ã³ã³ããŒãã³ããåŠçããæ¹æ³ãåŠç¿ããŸãã
ããã¯ãšã³ã
ãã®ã¬ã€ãã§ã¯ãäž»ã«Vueã®ããã³ããšã³ãã«çŠç¹ãåœãŠãŸãã RESTããã¯ãšã³ãã®äœæã«ã€ããŠã¯èããŸããã ããšãã°ãREST APIã®åœ¢åŒã§ã¹ã¿ããæäŸããjsonplaceholder.typicode.comãµãŒãã¹ã䜿çšããŸãã
ããã³ããšã³ã
ããŒã«
Vueã䜿ãå§ããã®ã¯ç°¡åã§ãã é©åãªããŒã«ã®äœ¿çšã¯ããã«ç°¡åã§ãã ããŒã«ãã³ã³ããŒãã³ããã©ã€ãã©ãªããã¹ãŠã®æ©äŒã®ãã©ã°ã€ã³ã®ãªã¹ããå«ãvue-awesomeãããžã§ã¯ããã芧ã«ãªãããšããå§ãããŸãã
ãŽãŒã¯ãª
æ°ãããããžã§ã¯ããäœæãããšãã¯ãVue-cliã䜿çšããããšããå§ãããŸãã ãã®ãããå ¬åŒã®Vueãã³ãã¬ãŒããããžã§ã¯ãããŸãã¯å€ãã®ãªãŒãã³ãœãŒã¹ãã³ãã¬ãŒããããžã§ã¯ãã®1ã€ã䜿çšããŠãããžã§ã¯ããäœæã§ããŸãããã¡ãããç¬èªã®ãããžã§ã¯ããäœæããŠãã©ãã§ã䜿çšã§ããŸãã
ãããã£ãŠããŸãã¯vue-cliãã°ããŒãã«ããã±ãŒãžãšããŠã€ã³ã¹ããŒã«ããŸãã
$ npm install -g vue-cli
次ã«ãéžæãããã³ãã¬ãŒãã§ãããžã§ã¯ããåæåããŸãã ãã®äŸã§ã¯ãwebpack-simpleã§ååã§ãã
$ vue init webpack-simple vue-spa
次ã«ãvue-spaãã©ã«ããŒã«ç§»åããã¿ãŒããã«ã§npm installãå®è¡ããŸãã ãã¹ãŠã®ããã±ãŒãžãã€ã³ã¹ããŒã«ããããã¢ããªã±ãŒã·ã§ã³ãéçºã¢ãŒãã§å®è¡ã§ããŸãã
$ npm run dev
ãã®ã³ãã³ãã¯ãããŒã«ã«webpack devãµãŒããŒã§ãããžã§ã¯ããèªåçã«èµ·åããŸãã æãã·ã³ãã«ãªVueã¢ããªããã©ãŠã¶ãŒã«è¡šç€ºãããŸãã ãã¡ãããããã¯ç§ãã¡ãæãããã«ãã¹ãŠãèŠãŠããŸããããããŠãããã«äœããå§ããããã®åºçºç¹ãšããŠã®ã¿é©ããŠããŸãã äœæ¥ãç¶è¡ããã«ã¯ããŸããã³ãã¬ãŒãã®æ§é ã«æ £ããããšããå§ãããŸãã
Webpackã·ã³ãã«ãã³ãã¬ãŒã
webpack-simpleãã³ãã¬ãŒãã®å éšã«ã¯æ¬¡ã®æ§é ããããŸãã
index.htmlãã¡ã€ã«ã«ã¯ãæ¬æã«åäžã®ãappãèŠçŽ ãæã€åçŽãªHTMLããŒã¯ã¢ãããå«ãŸããŠããŸãã vueã«ãã£ãŠçæãããDOMã«çœ®ãæããããŸãã ãã®ããã bodyã¿ã°ã¯ã«ãŒãèŠçŽ ãšããŠæšå¥šãããŠããŸããã
srcãã©ã«ããŒã«ã¯ãwebpackãšã³ããªãã€ã³ããå«ãmain.jsãã¡ã€ã«ãå«ãŸããŠããŸãã Vueã³ã³ããŒãã³ããããã«ã€ã³ããŒããããŸãã ãŸããVueã®ã«ãŒãã€ã³ã¹ã¿ã³ã¹ã«ã€ããŠã説æããŸããããã«ã¯ããããŸã§2ã€ã®ããããã£ããããŸãã ãelãããããã£ã¯ãæå®ãããDOMèŠçŽ ãžã®ãªã³ã¯ãVueã€ã³ã¹ã¿ã³ã¹ã«æäŸããŸãã ãã1ã€ã¯ã App.vueããDOMãçæããã¬ã³ããªã³ã°é¢æ°ã§ãã äžè¬ã«ãwebpack-simpleãã³ãã¬ãŒãã®æ§é ã«ã€ããŠç¥ãå¿ èŠãããã®ã¯ããã ãã§ãã ã¢ããªã±ãŒã·ã§ã³ã®äž»èŠéšåã¯App.vueã§ããã°ã©ã ãããŸãã .vueæ¡åŒµåã¯ããã¡ã€ã«ãvueã®åäžãã¡ã€ã«ã³ã³ããŒãã³ããšããŠå®çŸ©ããŸãã ããã¯ãVueã®æ©èœã®1ã€ã§ãããããããããã«è©³ããç¥ãããšãã§ããŸãã
åäžãã¡ã€ã«ã³ã³ããŒãã³ã
å* .vueãã¡ã€ã«ã¯ã3ã€ã®ã¿ã€ãã®ãããã¯ã§æ§æãããŸãïŒ<ãã³ãã¬ãŒã>ã<ã¹ã¯ãªãã>ãããã³ãªãã·ã§ã³ã§<ã¹ã¿ã€ã«>ã ãã®çµæããããžã§ã¯ããé¢é£ããã³ã³ããŒãã³ãã«åå²ã§ããŸãã ã³ã³ããŒãã³ãã®å éšã§ã¯ããã®ãã³ãã¬ãŒããããžãã¯ãããã³ã¹ã¿ã€ã«ã¯å¯æ¥ã«ãªã³ã¯ãããŠããããããã®çµã¿åããã«ãããå®éã«ã¯ã³ã³ããŒãã³ããããå šäœçãã€å®¹æã«ç¶æãããŸãã ããã§ãVueã§ããã°ãäœæããæºåãæŽããŸããã
ã¢ããªã±ãŒã·ã§ã³ãæžã
å®éã«äœãå®è£ ããã®ãèŠãŠã¿ãŸãããã ããŒãžäžéšã«ããã°ã®ååã®èŠåºãããããŸãã å·ŠåŽã«ã¯ãæçš¿ã®ã¿ã€ãã«ã衚瀺ããåºå®ãµã€ãããŒããããŸããããã¯ç®æ¬¡ã®ãããªãã®ã«ãªããŸãã ããŒãžã®æ®ãã®éšåã¯ãã¬ã³ãŒãã®ããã¹ãã衚瀺ãããåçãããã¯ã§å ããããŸãã
ã¹ããã1
ãŸããApp.vueããäœåãªè¡ããã¹ãŠåé€ããŸãã ãããŠãèŠä»¶ã«åŸã£ãŠãã³ãã¬ãŒããæžãæããŸãã
<template> <div id="app"> <header> <h1>Vue.js SPA</h1> </header> <main> <aside class="sidebar"> </aside> <div class="content"> </div> </main> </div> </template>
次ã«ãdataããããã£ã䜿çšããŠVueã€ã³ã¹ã¿ã³ã¹ãäœæããã¡ãã»ãŒãžãšãšãã«é åã«é 眮ããŸãã çŸæç¹ã§ã¯ç©ºã§ãããããã«ã¢ã¬ã€å ã®ãµãŒããŒããåä¿¡ããããŒã¿ãå ¥ããŸãã
æåã®åŒã³åºãåŸãã«ãŒãããŒã¿ãªããžã§ã¯ãã«ãªã¢ã¯ãã£ãããããã£ãè¿œå ã§ããªããªããŸãã ãããã£ãŠãVueã®ã€ã³ã¹ã¿ã³ã¹ãäœæããåã«ããã¹ãŠã®ãªã¢ã¯ãã£ãããããã£ãã«ãŒãã¬ãã«ã§å®£èšããããšããå§ãããŸãã
<script> export default { data () { return { posts: [] } } } </script>
ãŸããããã€ãã®ã¹ã¿ã€ã«ãè¿œå ããŠãã¢ããªã®èŠæ ããè¯ãããããšãã§ããŸãã
ã¢ããªã±ãŒã·ã§ã³ã³ãŒãã¯github.comã§ãã¹ããããŠããŸã ã ãªããžããªã®ã¯ããŒã³ãäœæããã¹ãããçªå·ã§ãã©ã³ããåãæ¿ããã ãã§ãã¢ããªã±ãŒã·ã§ã³ã®éçºãã¹ãããããšã«è¿œè·¡ã§ããŸãã次ã«äŸã瀺ããŸãã
$ git checkout step-1
çŸæç¹ã§ã¯ãããã²ãŒã·ã§ã³ããã«ã«è¡šç€ºãããã®ã¯ãŸã£ãããªãã®ã§ããµãŒããŒããããŒã¿ãååŸããŸãããã ãã®ããã䜿ããããHTTPã¯ã©ã€ã¢ã³ãã§ããAxiosãéžæããŸããã ãŸããVueãªãœãŒã¹ãç¬èªã®éžæãjQuery Ajaxãªã©ã䟿å©ãªæ¹æ³ã䜿çšããããšãã§ããŸãã
ã¹ããã2
Axiosãã€ã³ã¹ããŒã«ãã
$ npm install --save-dev axios
次ã«ããããAppã³ã³ããŒãã³ãã«ã€ã³ããŒããããµãŒããŒã«èŠæ±ãéä¿¡ããŠãããpostsããããã£ã«å²ãåœãŠãgetAllPostsïŒïŒã¡ãœãããå®çŸ©ããŸãã createdïŒïŒããã¯ã§ã¡ãœãããåŒã³åºããŸããããã¯ãVueã€ã³ã¹ã¿ã³ã¹ã®äœæåŸãããã³ããŒã¿ã¢ã¯ã»ã¹èšå®ã®èšå®åŸã«åŒã³åºãããŸãã
import axios from 'axios' export default { data () { return { posts: null, endpoint: 'https://jsonplaceholder.typicode.com/posts/', } }, created() { this.getAllPosts(); }, methods: { getAllPosts() { axios.get(this.endpoint) .then(response => { this.posts = response.data; }) .catch(error => { console.log('-----error-------'); console.log(error); }) } } }
ãããŠããµã€ãããŒã«ãã¹ãŠã®ã¬ã³ãŒãããããŒã衚瀺ããŸãã
<aside class="sidebar"> <div v-for="post in posts"> {{ post.title }} </div> </aside>
ãããŸã§ãã¬ã³ãŒãã®ã¿ã€ãã«ã®ã¿ã衚瀺ããŸãããããããŸã§ã®ãšãããã¬ã³ãŒãèªäœã¯è¡šç€ºã§ããŸããã 次ã«ããµã€ãããŒã§éžæããååã«åŸã£ãŠãã³ã³ãã³ãã»ã¯ã·ã§ã³ã«å®å šãªæçš¿ã衚瀺ããå¿ èŠããããŸãã åæã«ãåãšã³ããªãäžæã®ã¢ãã¬ã¹ã§å©çšã§ããããã«ããããšæããŸãã
ã¹ããã3
ãããè¡ãã«ã¯ãå ¬åŒã®Vueã©ã€ãã©ãªvue-routerã䜿çšããŸãã ååã瀺ãããã«ãã©ã€ãã©ãªã䜿çšãããšãã¢ããªã±ãŒã·ã§ã³ã®ã«ãŒãã£ã³ã°ãæ§æã§ããŸãã
ã©ã€ãã©ãªãã€ã³ã¹ããŒã«ããŸãã
$ npm install --save-dev vue-router
ã«ãŒãã£ã³ã°ãèšå®ããããã«ãmain.jsã«æ»ããŸãããã ããã§ãã«ãŒãã£ã³ã°èšå®ãå®çŸ©ããVueã€ã³ã¹ã¿ã³ã¹ã«è¿œå ããŸãã
import Vue from 'vue' import Router from 'vue-router' import App from './App.vue' import Post from './components/Post.vue' import Hello from './components/Hello.vue' Vue.use(Router) const router = new Router({ routes: [ { path: '/', name:'home', component: Hello, }, { path: '/post/:id', name:'post', component: Post, props: true, }, ] }) new Vue({ el: '#app', render: h => h(App), router })
ã«ãŒãã£ã³ã°èšå®ã§ã¯ã察å¿ãããã¹ã«æ²¿ã£ãŠã¬ã³ããªã³ã°ããã³ã³ããŒãã³ããæå®ããŸããã åæçš¿ã®ã¬ã³ããªã³ã°ã¯Post.vueã³ã³ããŒãã³ãã®ã¿ãæ åœãããããåæçš¿ãžã®ãã¹ã決å®ããå¿ èŠã¯ãããŸãããåçãã¹ãå®çŸ©ããã ãã§ååã§ãã
path: '/post/:id'
ãã®ãã¹ã«ã¯ãç¹å®ã®æçš¿ãæãåçã»ã°ã¡ã³ãIDãå«ãŸããŸãã åæã«ããããä»ããŠPostã³ã³ããŒãã³ãã®ãã®ã»ã°ã¡ã³ãã«ã¢ã¯ã»ã¹ã§ããŸã$ Route.params.id ã ãã ããã³ã³ããŒãã³ãã§$ã«ãŒãã䜿çšãããšãç¹å®ã®URLã§ã®ã¿äœ¿çšã§ãããããã«ãŒããšã®ç·å¯ãªæ¥ç¶ãä¿®æ£ãããã³ã³ããŒãã³ãã®æè»æ§ãå¶éãããŸãã 代ããã«ã propsãªãã·ã§ã³ã䜿çšããŠtrueã«èšå®ã§ããŸã ã ãã®åŸã$ route.paramsã¯Postã³ã³ããŒãã³ãã®propsãªãã·ã§ã³ã«é¢é£ä»ããããŸãã
ã«ãŒã¿ãŒãäœæããã®ã§ãã¢ããªã±ãŒã·ã§ã³ã«æ»ãããã³ãã¬ãŒãã«ããã«æ°è¡ãè¿œå ã§ããŸãã
<main> <aside class="sidebar"> <router-link v-for="post in posts" active-class="is-active" class="link" :to="{ name: 'post', params: { id: post.id } }"> {{post.id}}. {{post.title}} </router-link> </aside> <div class="content"> <router-view></router-view> </div> </main>
ããã«ã¯ã2ã€ã®vue-routerã³ã³ããŒãã³ãããããŸãïŒ<router-link>ããã³<router-view>ã 1ã€ã¯ãã«ãŒãã£ã³ã°ããµããŒãããã¢ããªã±ãŒã·ã§ã³ã§ãŠãŒã¶ãŒããã²ãŒã·ã§ã³ãæå¹ã«ããããã®ã³ã³ããŒãã³ãã§ãã 2çªç®ã®ã³ã³ããŒãã³ãã¯ãç¹å®ã®ãã¹ã«å¯ŸããŠäžè²«ããã³ã³ããŒãã³ããæç»ããæ©èœã³ã³ããŒãã³ãã§ãã
æåŸã®ã¹ãããã¯æ®ã£ãã æçš¿ãšã³ããªã®å 容ã衚瀺ããå¿ èŠããããŸãã
ã¹ããã4
Post.vueãã¡ã€ã«ã«ç§»ããŸããããããã§ã¯ãåçŽãªãã³ãã¬ãŒããè¿œå ããŸãã
<template lang="html"> <div class="post" v-if="post"> <h1 class="post__title">{{ post.title }}</h1> <p class="post__body">{{ post.body }}</p> <p class="post__id">{{ post.id }}</p> </div> </template>
次ã«ããã®ã³ã³ããŒãã³ãã®Vueã€ã³ã¹ã¿ã³ã¹ã®ãã©ã¡ãŒã¿ãŒãèšå®ããå¿ èŠããããŸãã ããã§ã¯ããã¹ãŠããã¹ãŠã®æçš¿ã®è¡šç€ºèšå®ãšåãã§ãã idãå€æŽããŠpropsãªãã·ã§ã³ã宣èšããŸããããã¯ãæçš¿ã®çªå·ãåãåããŸãã 次ã«ãApp.vueã§æ¢ã«è¡ãããŠããããã«ãããŒã¿ãªããžã§ã¯ãã宣èšããŸãã
import axios from 'axios'; export default { props: ['id'], data() { return { post: null, endpoint: 'https://jsonplaceholder.typicode.com/posts/', } } }
次ã«ã getPostïŒïŒã¡ãœããã«ã€ããŠèª¬æããŸãããã®ã¡ãœããã¯ãèå¥åã«ãã£ãŠ1ã€ã®æçš¿ã¬ã³ãŒãã®ã¿ãåãåãã äœæãããïŒïŒããã¯ã§åŒã³åºããŸãã
methods: { getPost(id) { axios(this.endpoint + id) .then(response => { this.post = response.data }) .catch( error => { console.log(error) }) } }, created() { this.getPost(this.id); },
ã»ãŒå®äºã ããã§ã¢ããªã±ãŒã·ã§ã³ãèµ·åãããšãURLã¯å€æŽãããŸãããæåã«æãããå¯äžã®æçš¿ã衚瀺ãããŸãã å®éã«ã¯ãç°ãªãæçš¿ãã¬ã³ããªã³ã°ããããã«åãã³ã³ããŒãã³ãããããVueã¯ãªãœãŒã¹ã®äžå¿ èŠãªç¡é§ã®ããã«åäœæããå¿ èŠããããŸãããããã¯ãã³ã³ããŒãã³ãã®ã©ã€ããµã€ã¯ã«ããã¯ãåŒã³åºãããªãããšãæå³ããŸãã
ãããä¿®æ£ããã«ã¯ã $ã«ãŒããªããžã§ã¯ãã®ãŠã©ããã£ãŒãã€ã³ã¹ããŒã«ããã ãã§ãã
watch: { '$route'() { this.getPost(this.id); } }
ããã§ãã¹ãŠãæ£åžžã«æ©èœããããã«ãªããŸããã å®åçšã®ããŒãžã§ã³ãååŸããã«ã¯ãã³ã³ãœãŒã«ã§npm run buildã³ãã³ããå®è¡ããã ãã§ãã
ãŸãšãããš
4ã€ã®ã¹ãããã§Vueã䜿çšããç°¡åãª1ããŒãžã®ã¢ããªã±ãŒã·ã§ã³ãäœæããŸããã vue-cliã䜿çšããŠãããžã§ã¯ããéå§ããã®ãããã«ç°¡åããåŠã³ãŸããã ãããžã§ã¯ããããæè»ã§ã¹ã±ãŒã©ãã«ã«ããåäžãã¡ã€ã«Vueã³ã³ããŒãã³ãã®æŠå¿µãæ€èšããŸããã Axiosã䜿çšããŠå€éšAPIããããŒã¿ãæœåºããæ¹æ³ãåŠã³ãŸããã ãããŠãvue-routerã䜿çšããŠã«ãŒãã£ã³ã°ãæ§æããæ¹æ³ãèŠãŸããã ãã¡ãããããã¯åºæ¬çãªç¥èã§ããããããé«åºŠãªæ©èœã䜿çšããŠVue.jsã䜿ãå§ããã®ã«åœ¹ç«ã€ããšãé¡ã£ãŠããŸãã
䟿å©ãªãªã³ã¯
â ãªãªãžãã«èšäº
â èšäºã®ãœãŒã¹ã³ãŒãã䜿çšããŠGitHubãããžã§ã¯ãã«ãªã³ã¯ãã
â Project vue-awesome