# CH7 より大規模なアプリケーション開発
# コラム なぜ抽象化が必要なの?
このコラムはどうも抽象化言いたいだけでは?みたいになっているので、次の増刷があれば少し書き直す予定です。
- コードを抽出しよう:
ある程度の範囲でコードをまとめて抜き出すとメンテしやすくなる(ユーザー情報・商品情報など) - コードを共通化しよう:
同じ処理を行っている場合は、関数で共通化するとメンテしやすくなる(算出処理など) - 依存しないコードを書こう:
たとえば、ポチがご飯を食べる処理をするとき「ドッグフードを食べる」と具体的に書いてしまうと、登場する動物の数だけ処理を書かなくてはいけないし、ドッグフード以外のものが食べられない…。
# S35 単一ファイルコンポーネントとは
221~225ページ
<template>
<div class="example">
<span class="title">{{ text }}</span>
</div>
</template>
<script>
export default {
name: 'Example',
data() {
return {
text: 'example'
}
}
}
</script>
<!-- scoped CSS -->
<style scoped>
.title {
color: #ffbb00;
}
</style>
# S37 Node.js の導入
# S38 Vue CLI の導入
231~237ページ
# Vue CLI のインストール
npm install -g vue-cli
# 新しいプロジェクトの作成
vue init webpack my-app
最後に自動でインストールが開始されない場合は、次のコマンドで my-app
ディレクトリに移動してモジュールをインストールしてください。
cd my-app
npm install
# フォルダとファイルの構成
234ページ
次のように、ルートコンストラクタのテンプレートを描画関数に変更してそれ以外はすべて「.vue」ファイルを使用することで、ランタイム限定ビルド(ややコンパクトサイズ)の Vue.js を利用できます。 テンプレートオプションを使用していると、コンパイルが必要になるためランタイム限定ビルドは利用できません。
new Vue({
el: '#app',
components: { App },
template: '<App/>'
})
new Vue({
el: '#app',
render: h => h(App)
})
ランタイムってなに?
ランタイム限定の「ランタイム」とは作成したアプリケーションを動かすために必要なコードのことをいいます。 コンパイラを含まず最低限になるため、少しサイズが小さくなります。
完全ビルドは、テンプレートを描画関数に変換する「コンパイラ」も含んだコードです。 そのため、webpack などを使って事前にコンパイルしておけば、コンパイラは不要になります。
# [おまけ] Vue CLI バージョン3
ここからは、Vue CLI3の説明です。
WARNING
バージョン3のドキュメントは、リポジトリの「docs」フォルダに英語版がありますが、日本語はまだ整備されていません。 また、ベータ版のため仕様に変更が入ることもあります。不安がある場合はバージョン2を使用してください。
# Vue CLI3 のインストール
npm install -g vue-cli
の代わりに、次のコマンドで現在開発中のバージョン3の Vue CLI をインストールできます。
npm install -g @vue/cli
# or yarn がいい場合は…
yarn global add @vue/cli
# プロジェクトの作成方法
プロジェクトの作成は vue init webpack my-app
の代わりに、次のコマンドを使用します。
# プロジェクトの作成
vue create my-app
Vue CLI3 では、質問内容がだいぶ異なります。 また、テンプレートを指定するのではなく、質問に答えて必要なパッケージを選択します。 学習では、一番最初のプリセットで「simple」を選択するか、「Manually select features」を選択して「Babel」「CSS Pre-processors」のみを選択するのがオススメです。 上下の矢印キーで項目移動、スペースキーでチェックが付けられます。
Vuex と Vue Router については、インストール手順から説明しているため、この時点ではインストールしなくても問題ありません。 最初の質問でプリセットを選択した場合は、すぐにモジュールのインストールが開始されます。
Vue CLI3 ではビルドツール用のファイルは、ほぼすべて隠蔽されるため、フォルダがスッキリとします。
ビルド設定のカスタマイズは、プロジェクトルートに vue.config.js
というファイル作成してそこに追加していきます。
# ディレクトリ構造
「src」ディレクトリの中身はバージョン2と同じです。「public」フォルダには、インデックスの HTML のテンプレートとなる「index.html」ファイルと、ローダーを介さずそのまま公開する静的ファイルが入ります。(つまり、バージョン2の「static」フォルダと同じ)
.git/ 3では最初から作成される!✨
public/ そのまま公開したいファイル
src/
├ assets/
├ components/
├ App.vue
└ main.js
.git/
public/
src/
├ assets/
├ components/
├ store/ Vuex モジュール
├ views/ ページ用コンポーネント
├ App.vue
├ main.js
├ router.js
└ store.js
開発サーバーの起動のコマンドも変わり、次のようになります。
npm run serve
# or
yarn serve
# S39 Vue.jsプラグイン
238~241ページ
# プラグインを自作してみよう
238ページ
var windowPlugin = {
install: function(Vue) {
// プラグインデータ用にVueインスタンスを利用する
var store = new Vue({
data: {
scrollY: 0
}
})
// ウィンドウのスクロールイベントをハンドル
var timer = null
window.addEventListener('scroll', function() {
if (timer === null) {
timer = setTimeout(function() {
// 200ms間隔でscrollYプロパティに代入
store.scrollY = window.scrollY
clearTimeout(timer)
timer = null
}, 200)
}
})
// インスタンスプロパティに登録
Vue.prototype.$window = store.$data
}
}
Vue.use(windowPlugin)
Vue.component('my-component', {
template: '<div>{{ scrollY }}</div>',
computed: {
scrollY: function() {
return this.$window.scrollY
}
}
})
# S40 ES2015 で書いてみよう
242~250ページ
# 変数宣言の書き方
let x = 0
console.log(x++) // -> 1
const x = 0
console.log(x++) // -> Identifier 'x' has already been declared
{
let x = 1
}
console.log(x) // -> x is not defined
const array = [1, 2]
array.push(3)
console.log(array) // -> (3) [1, 2, 3]
array.length = 0
console.log(array) // -> []
# 関数とメソッドの書き方
# function の省略
new Vue({
methods: {
handleClick() { ... }
}
})
# アロー関数
const newArray = array.map(el => {
return el * 2
})
const newArray = array.map(el => el * 2)
const newArray = array.map((el, index) => el * 2)
const newArray = array.map(el => ({ value: el * 2 }))
# テンプレートリテラル
const name = 'たま'
const template = `
<div class="template">
<strong>${ name }</strong>
</div>`
console.log(template)
# プロパティのショートハンド
const a = 'foo'
const b = 'bar'
const newObject = { a, b }
# 分割代入
// 配列要素1,2をそれぞれ変数a,bに代入
const [a, b] = [1, 2]
console.log(a) // -> 1
// nameプロパティだけ代入
const { name } = { id: 1, name: 'りんご' }
console.log(name) // -> りんご
function myFunction({ id, name }) {
console.log(name) // -> りんご
}
myFunction({ id: 1, name: 'りんご' })
# スプレッド演算子
const array = [1, 2, 3]
// バラバラの3つの引数として渡す
myFunction(...array)
// arrayを展開して4を加えた新しい一次配列を作成
const newArray = [...array, 4] // -> (4) [1, 2, 3, 4]
# 配列メソッド
# find
const array = [
{ id: 1, name: 'りんご' },
{ id: 2, name: 'ばなな' }
]
const result = array.find(el => el.id === 2)
console.log(result) // -> { id: 2, name: 'ばなな' }
# findIndex
const array = [
{ id: 1, name: 'りんご' },
{ id: 2, name: 'ばなな' }
]
const result = array.findIndex(el => el.id === 2)
console.log(result) // -> 1
# Promise
function myFunction() {
return new Promise((resolve, reject) => {
setTimeout(() => {
// 成功したことを通知
resolve('success!')
}, 1000)
})
}
// 1秒後にmyFunctionが終わった知らせを受けてthenの処理が行われる
myFunction().then(value => {
console.log(value) // -> success!
})
function myFunction(num) {
return new Promise((resolve, reject) => {
if (num < 10) {
resolve('success!')
} else {
reject('error!')
}
})
}
myFunction(100).catch(value => {
console.log(value) // -> error!
})
myFunction().then().catch().finally(() => {
// 成功でも失敗でも行われる
})