ミニマムなVue.jsコンポーネントプログラミングその1(シングルコンポーネント)


Vue.jsを使うと、コンポーネントプログラムというものの楽しさを体感できると思います。(正確に言うと、vue-cliを使ってコンポーネントプログラムを構成すると、かな?)

Web Componentsという概念も最近知ったところですが、MVCという概念に沿って、

  • データモデル定義(M)
  • UI構造(V)
  • データモデルとUI構造の制御インタフェースであるコントローラ(C)

みたいな感じにフォルダをバラバラに分けて管理するのはもう古い、ということなのかも。(適材適所はあるでしょうが)

最終的にやりたいのは、SPAライクなクライアントアプリです。

従って、
ルータを内包し、
サーバサイドレンダリングはせず、
データはResutFul APIサーバを立ててアクセスし、
アプリ自体は部品(コンポーネント)を組み合わせてつくる、
そんなテーマで進めたいと思います。

そして応用編まで行けたら、Typescriptと組み合わせたモダンな記法とか、やってみたいところです。まずはVue.jsネイティブの理解が必要ですけれども。

今回はシングルコンポーネントだけで構成されたVue.jsアプリを組んでみます。

環境

vue-cli 4.3.1

プロジェクト作成

vue create vue_sample
? Please pick a preset: 
  VueSample (typescript, router) 
  default (babel, eslint) 
❯ Manually select features 

まずはミニマム構成を用意したいので、マニュアルを指定。

? Check the features needed for your project: 
❯◉ Babel
 ◯ TypeScript
 ◯ Progressive Web App (PWA) Support
 ◯ Router
 ◯ Vuex
 ◯ CSS Pre-processors
 ◯ Linter / Formatter
 ◯ Unit Testing
 ◯ E2E Testing

JavaScriptの新しい記法は使いたいので、Babelを選択し、後はオフ。後の設定はデフォルトとして、プロジェクトを作成。

コンポーネント構造をミニマム化

公開するindex.htmlは、


<div id="app"></div>

となっており、すでにミニマムです。

エントリポイントであるmain.jsは、


import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')

となっており、vueの基幹ライブラリのみimport、
唯一Appコンポーネントのみマウントしており、
こちらもすでににミニマムです。

App.vueを以下のように書き直します。

<template>
  <div>
    <h1>Hello, Vue.js</h1>
  </div>
</template>

<script>
export default {
  name: 'App'
}
</script>

UIの構造をテンプレート定義し、データモデルとコントローラを内包可能なVueインスタンスを定義/生成します。

  • UIの構造は見出しのみ(h1)
  • コンポーネントも名称のみ定義(name: 'App')

以上により、h1要素のみ備えたAppコンポーネント(Vueインスタンス)をレンダリングするだけのミニマムなプロジェクトが完成します。

npm run serveして、localhost:8081とかにアクセスすると、

超シンプルな画面がレンダリングされました。

補足

Vue.jsの長所の一つに、「プログレッシブなフレームワーク」という文言がありますが、つまりこれは、

  • 便利なデータバインディングのみ使う
  • 再利用性の高いコンポーネント設計を導入する

等々、シーンに応じた導入ができるフレキシブルさを指していると思います。SPAにしたければ内部ルータを埋め込んだり。

今回のようなシンプルなケースでは、データバインディングのみ使った
非コンポーネントVue.jsプログラミングで全然間に合いますが、ヘッダ、フッタ等、画面が増えていけばどうしても部品を組み合わせたくなってくるのでコンポーネント設計を取り組んでみます。

次回

次回はこのミニマムなコンポーネントの上に、ミニマムな画面遷移(vue-router)を乗せていこうと思います。