そうだ、教祖になろう。出エジプト記 第4章2節 Vue.jsを思い出す
いつのことだか 思い出してごらん
第4章1節 Cloud9にVue.js開発環境を導入するでは
vue create プロジェクト名
でVue.jsを導入しました。
色々入ってます。
Vue.jsに触ったのは2年前でどういう構造になっていたのか忘れてしまいましたので、おさらいしてみましょう。
ディレクトリ構成はこんな感じです。
あんなこと こんなこと あったでしょう
1ファイルずつ見ていきましょう。
public/index.html
public配下はトランスパイルされない、そのまま静的コンテンツになるソースです。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <link rel="icon" href="<%= BASE_URL %>favicon.ico"> <title>clientside</title> </head> <body> <noscript> <strong>We're sorry but clientside doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> </noscript> <div id="app"></div> <!-- built files will be auto injected --> </body> </html>
<div id="app"></div>
の部分にビルドされたJavaScriptがバインドされます。
src/main.js
import Vue from "vue"; import App from "./App.vue"; import router from "./router"; import store from "./store"; Vue.config.productionTip = false; new Vue({ router, store, render: h => h(App) }).$mount("#app");
index.html
の#app
にApp.uve
をバインドするメインのJavaScriptです。
Vue Routerのrouter
とVuexのstore
を読み込んでいます。
src/App.vue
<template> <div id="app"> <div id="nav"> <router-link to="/">Canaan</router-link> | <router-link to="/about">Egipt</router-link> </div> <router-view /> </div> </template> <style lang="stylus"> #app font-family 'Avenir', Helvetica, Arial, sans-serif -webkit-font-smoothing antialiased -moz-osx-font-smoothing grayscale text-align center color #2c3e50 margin-top 60px </style>
.vue
ファイルの構成です。
<template>
でHTML、<script>
でJavaScript、<style>
でCSSを定義します。
このファイルがJavaScriptを使ってないんで<script>
はありません。
<template>
のrouter-link
はVue Routerのパスです。
Vue Routerは、SPAでサーバとの通信なしで画面を切り替える仕組みです。
ビルドすると<a>
タグになります。
選択したパスに対応するコンポーネントが<router-view />
に表示されます。
パスやコンポーネントはsrc/router/index.js
で定義されます。
<style>
はStylusで定義されます。
CSSメタ言語のStylusはトランスパイスされてCSSになります。
直接CSSを書くときの{}
や;
が不要で、変数を使えたりもします。
src/router/index.js
import Vue from "vue"; import VueRouter from "vue-router"; import Home from "../views/Home.vue"; Vue.use(VueRouter); const routes = [ { path: "/", name: "home", component: Home }, { path: "/about", name: "about", // route level code-splitting // this generates a separate chunk (about.[hash].js) for this route // which is lazy-loaded when the route is visited. component: () => import(/* webpackChunkName: "about" */ "../views/About.vue") } ]; const router = new VueRouter({ mode: "history", base: process.env.BASE_URL, routes }); export default router;
Vue Routerのパスとコンポーネントの対応を定義します。
"/"
に対してはHome
、"/about"
に対しては"../views/About.vue"
を動的にインポートしています。
SPAでは画面を切り替えないのでブラウザの履歴機能をシミュレートするためにのmode: "history"
を指定しています。
スライドショー作るだけなら要らなかったかな。
まあ使わなかったら消しましょう。
src/store/index.js
import Vue from "vue"; import Vuex from "vuex"; Vue.use(Vuex); export default new Vuex.Store({ state: {}, mutations: {}, actions: {}, modules: {} });
VuexのStateやActionを定義します。
本家によると「 Vuex は Vue.js アプリケーションのための 状態管理パターン + ライブラリです。」
SPAだとJavaScriptでデータを保持していろんなトリガで画面に反映するので、ばらばらに実装するとすぐにコードがスパゲッティになります。
ので、一元的なデータストアから画面に直接反映させる仕組みです。
ちょっとよくわからないので、実装するときに詳しく見ていきましょう。
src/view/Home.vue
<template> <div class="home"> <img alt="Vue logo" src="../assets/logo.png" /> <HelloWorld msg="Welcome to Your Vue.js App" /> </div> </template> <script> // @ is an alias to /src import HelloWorld from "@/components/HelloWorld.vue"; export default { name: "home", components: { HelloWorld } }; </script>
Vue Routerで"/"
が選択されたときに読み込まれるコンポーネントです。
子コンポーネントのHelloWorld
をインポートして<HelloWorld>
タグとして配置しています。
引数としてmsg
を渡してます。
src/components/HelloWorld.vue
<template> <div class="hello"> <h1>{{ msg }}</h1> (略) </div> </template> <script> export default { name: "HelloWorld", props: { msg: String } }; </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped lang="stylus"> (略) </style>
引数のmsg
を受け取って<h1>
タグに埋め込んでます。
大体の構造は思い出した気がしますので、次回から実装に移っていきたいと思います。