シャッフル主任の進捗報告

興味のあるものを作ります。進捗を不定期にご報告します。

そうだ、教祖になろう。出エジプト記 第4章2節 Vue.jsを思い出す

いつのことだか 思い出してごらん


第4章1節 Cloud9にVue.js開発環境を導入するでは

vue create プロジェクト名

でVue.jsを導入しました。
色々入ってます。
Vue.jsに触ったのは2年前でどういう構造になっていたのか忘れてしまいましたので、おさらいしてみましょう。

ディレクトリ構成はこんな感じです。

f:id:chief-shuffle:20191222101117j:plain

あんなこと こんなこと あったでしょう


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#appApp.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 アプリケーションのための 状態管理パターン + ライブラリです。」

vuex.vuejs.org

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>タグに埋め込んでます。

大体の構造は思い出した気がしますので、次回から実装に移っていきたいと思います。