単一ファイルコンポーネントを使って開発環境を強化する

Vue.js の単一ファイルコンポーネントを使えるようにします。

Vue.js はコンパイルしなくてもそのまま Web ブラウザで利用できるのも特徴なんですけど、やっぱり .vue ファイルを使ってみたい!

単一ファイルコンポーネント

単一ファイルコンポーネントはコンポーネント毎に .vue 拡張子のファイルに分けて作成して Webpack などで一つのスクリプトファイルにバンドルします。.vue ファイルの中にはコンポーネントの JavaScript コード、HTML テンプレート、CSS をまとめて書く事ができます。

このファイルを importrequire で読み込んで components に登録します。

child-comp.vue

<template>
<div class="demo">
  <span>{{ text }}</span>
</div>
</template>
<script>
export default {
  data() {
    return {
      text: 'demo'
    }
  }
}
</script>
<style scoped>
span { color: #ffbb00; }
</style>

main.js

import childComp from 'child-comp.vue'
new Vue({
  el: '#app',
  components: {
    childComp
  }
})

これは Vue の開発もだいぶ捗りそうです(•ө•)ノ

scoped CSS

スタイルシート定義に scoped を設定しておくとコンパイル時にコンポーネント内の要素につく data-v-xxxxxx という感じのユニークIDな属性と自動的に結び付けられます。自分でクラスを付けなくてもよくなり他のスタイルと競合する事が無くなるので基本的には scoped で書くと Good です。上の例だとコンポーネント内の span タグだけ文字色が変わります。なお、コンポーネントのルートタグには親と子の両方のIDが付くのでどちら CSS を書いても大丈夫です。

Vue-cliを使う場合

vue-cli は Vue プロジェクトの開発環境を自動的にセットアップするコマンドラインインターフェースです。予め Node.jsnpm のインストールが必要です。

ややこしい Webpack や ホットリロードの設定を作成してくれて、フォルダ構成にもあんまり悩まなくて良いです。単一ページ構成のサイトや SPA サイトを最初から作るならこれを使うとサクッと始められます。

npm install -g vue-cli
vue init (template-name) (project-name)
cd (project-name)
npm install

template-name

プロジェクトの雛形です。色々なテンプレートが用意されていますが、私は webpackwebpack-simple をよく使っています。基本的には webpack-simple で十分だしシンプルなので設定構成を追いやすいと思います。

手軽に試す Vue-cli の init (webpack-simpe)

npm install -g vue-cli
vue init webpack-simple vue-test
cd vue-test
npm install

インストールが終わったら以下のコマンドで Dev サーバーを起動します。

npm run dev

自動的にブラウザが開くと思います。このサーバーが立ち上がっている間はホットリロードが有効なので、ファイルを編集するとブラウザリロードしなくても編集した部分だけが更新されます。

webpack の方はデフォルトでCSSの抽出と、JavaScript をチャンク化してビルドします。自動テストを使いたかったりコードが大きくなるような場合こちらを選択すると楽でしょう。インストール時に ESLint や テストモジュールを使うかなどいくつか質問されます。

開発時のAPIのクロスドメイン対策

開発モードでは Node.js のサーバーを使って開発します。この時ホスト名はデフォルトだと localhost:8080 になりますが、本来は同じドメインにある API から JSON を取得するためにはプロキシを設定すると良いです。

config/index.js

proxyTable: {
  '/api': {
    target: 'http://example.com',
    changeOrigin: true
  }
}

これで http://example.com/api の JSON が /api で取得出来るようになります。

非SPAサイトでホットリロード機能を使う

Vue-cli のホットリロード最高かよ! Vue-cli を使ったサーバーでの開発では XAMPP などで作っているファイルは表示できませんがそんな非SPAサイトでもホットリロードを使う記事も書きました。こちらから

webpack-simpe で SASS/SCSS を使う

webpack の方はインストール時に「SASS使いますか?」と聞いてきますが、webpack-simple の方は自分でインストールする必要があります。

npm install -D node-sass sass-loader

でモジュールを追加して webpack.config.js を編集します。

      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: {
          loaders: {
            'scss': process.env.NODE_ENV === 'production' ? 
              'vue-style-loader!css-loader!sass-loader' : 
              'vue-style-loader!css-loader?sourceMap!sass-loader'
          }
          // other vue-loader options go here
        }
      },

上の記述例では SCSS を使用可能にして、ソースマップを開発モードでは有効、運用モードでは無効にします。ソースマップは圧縮前の記述位置を取得するために必要なものです。

package.json インストールする場所

package.json にはプロジェクトの情報や使用するモジュールとモジュールのバージョンなどが書かれています。

--save (-S) でインストールすると package.jsondependencies--save-dev (-D) でインストールすると devDependencies に追加されます。

基本は全部 devDependencies でも大丈夫なんですけど、開発で使うものは -D 実際にアプリで使うもの同梱するものは -S でインストールするのがセオリーみたいです。モジュールはコマンドラインからインストール・アンインストールして package.json を直接編集するのはなるべく避けると良いです。

Gulp+Babel+Webpack を使う場合

SPA じゃない場合は Gulp でやりたい場合もあります。モジュール化させたファイルを Webpack にまとめてもらい Babel でブラウザ用に変換して Gulp に編集をウォッチしてもらう事にします。自分で Webpack の設定とかしないといけないので vue-cli を使う場合よりも初期設定がやや面倒くさいです。

必要なモジュール

とりあえず Webpack と vue-loader というモジュールを使います。

  • vue-html-loader
  • vue-template-compiler(vueと同じバージョン)
  • css-loader
  • sass-loader(SASS/SCSS を使う場合)
  • node-sass(同上)
  • babel-loader
  • babel-preset-es2015

とりあえず上記あたりの開発に必要なモジュールを package.json に記述するか --save-dev を付けてインストールします。実際にアプリで使うライブラリの場合は --save でインストールします。

足りなければ足りないとエラーが出るはずなのです(っ'o'c)

gulpfile.js を書く

var gulp = require('gulp');
var webpack = require('webpack');

Webpack 自体凄い沢山設定があって覚えるの大変そうですね(´•ω•`)

[ERROR] 読み込みファイルがありません

.vue ファイルの中で SCSS の使用と変数定義用のファイルを @import を出来るようにしました。

watch タスクに登録します。

gulp.task('watch', function() {
  gulp.watch(['./src/**/*.js', './src/**/*.vue', './src/**/*.scss'], ['webpack.watch']);
});

CSSをファイルに抽出する

Webpack テンプレートの設定を参考にして、.vue の中の CSS コードを抽出してファイルに吐くようにしてみました。vue-loader のページにも載っています

[ERROR] 読み込みファイルがありません

ちょっと遅いのでやっぱりホットリロード神ですね(っ'ω'c)ෆ

まとめ

正直 Vue-cli がお手軽すぎてもうなんでも Vue-cli でいいじゃんみたいになってます。

とりあえず今まで何も考えずに jQuery で作っていた所はネイティブや Vue コンポーネントにしました。Vue は導入する場合全部作りなおさないとダメというわけじゃなくて、すこしづつ移行できるっていうのもいいですねー(๑'ᴗ'๑)

Vue を使い始めると DOM に直接アクセスする事は大分減りますが、それでも body タグとか Vue アプリの範囲外を操作したい時があります。ネイティブだとセレクタ操作は結構面倒くさいので、Selector というセレクタ処理に特化したライブラリを Vue と併用するのも良さそう。

さて、前回親子間のコンポーネントのやりとりをやったので、次回は非親子間のコンポーネントのやりとりについてやります。