[TOC]
# 学習資料
# Vue.jsとは
- 公式サイトより
- https://jp.vuejs.org/v2/guide/index.html#Vue-js-%E3%81%A8%E3%81%AF%EF%BC%9F
- ユーザーインターフェイスを構築するための**プログレッシブフレームワーク**です
※ プログレッシブフレームワーク:Vue.js作者のEvan You氏が提唱する概念。
アプリケーションの開発を進めていくと、様々な要件に対応するためにアプリケーションの規模も大きくなっていく。
そうすると、最初に導入したフレームワークが合わなくなり、乗り換えるために新しいフレームワークを模索しなければならないが、
Vue.jsは、サポートするツールやライブラリといったエコシステムの存在によって、アプリケーションの要求に柔軟に対応することが可能。
このように、どのような規模、段階のアプリケーションにも対応できるというのがプログレッシブフレームワークの概念。
下記のような特徴が挙げられる
- リアクティブなデータバインディング
- ファイルサイズが軽量(min+gzip圧縮16kb)
- SPAの作成が容易
- レンダリングが速い
## リアクティブなデータバインディング
- Vue.jsはDOMとJavaScriptのデータを同期するためにリアクティブな双方向データバインディングを提供している
### リアクティブ
外部からの入力や時間経過によってデータが変化した時に、変化した値を自動的に反映させる
### 双方向データバインディング
- 片方に変更があった場合にもう片方を 自動的 に変更すること
- データの変更が View に自動的に反映される
- View の変更がデータに自動的に反映される
## Vueで実現出来る機能
- JavaScriptライブラリを使用するプロジェクトへの導入が容易になる
- 高機能なシングルページアプリケーション(SPA)を構築することが可能
## 他のフレームワークとの違い(メリット)
- React
- https://jp.vuejs.org/v2/guide/comparison.html#React
- ReactとVueは類似点も多く速度もどちらも速い。
- 異なる点は Reactは描画関数のみ対応し、Vueは描画関数とJSXどちらも対応している点
- HTMLに近い記述が可能なため、HTMLの技術を持っている場合は読み書きが簡単になる
- Angular
- https://jp.vuejs.org/v2/guide/comparison.html#Angular-%E4%BB%A5%E5%89%8D%E3%81%AF-Angular-2-%E3%81%A8%E3%81%97%E3%81%A6%E7%9F%A5%E3%82%89%E3%82%8C%E3%82%8B
- 実行時の速度はどちらも高速
- ファイルサイズはVuex + Vue Router (gzip 済みで 〜 30 KB) を含むフル機能の Vue 2 プロジェクトは、初期状態のangular-cli製の コンパイル済みアプリケーション (gzip 済みで 〜 65 KB) よりもかなり軽量
- またVueはAngularよりも制約が少ない。様々なビルドシステムのための公式サポートを提供しており、アプリケーションをどのように構成するかについては制限していない
## Vueのモデル(MVVM)
- Model-View-ViewModelからなるモデル
- Model
- データの管理や保存、外部との入出力や内部的な処理を行う
- View
- 画面表示や画面上の入力・操作の受け付けを行う
- ViewModel
- ViewとModelの間に存在し、互いの状態の変更を通知し反映させる役割
- 設計としては、`.vue` ファイルの `<template>`(+`<style>`)部分がView、`<script>`がViewModel部分にあたり、Modelは内部のJSファイル等が担う

- MVC(Model-View-Controler)モデルと比べ、状態の変更を即座に表示に反映させることが出来る等のメリットがある
## Vueのファイル構成
- Vueは下記のファイル群からなる
```
vue
├── public
│ └── index.html ページ HTML
└── src
├── App.vue レイアウト vue
├── components
│ └── HelloWorld.vue コンポーネント vue
├── main.js 最初に実行される js
├── router.js Vue Router の設定
├── store.js Vuex の設定
└── views 各ページ
├── About.vue About ページ vue
└── Home.vue Home ページ vue
```
### srcフォルダ
主に編集するのはsrcフォルダとなる。srcフォルダには、「assets」「components」「views」という3つのフォルダに加えて、「App.vue」「main.js」「router.js」という3つのファイルが存在している。
### assetsフォルダ
画像やテストデータなど、静的なファイルを保管するフォルダ。
### componentsフォルダ
Vue.jsでは、ページ内の各要素(ヘッダー、フッター、リストなど)を「コンポーネント」という区分に小分けして管理する。
コンポーネントファイルの名前は大文字で始めることが慣習化している。
### viewsフォルダ
各ページ用のファイルを保管する場所です。コンポーネントがインポートされ使用されている。
Vue.jsアプリでは、ページ用のvueファイル側でコンポーネント用のvueファイルをインポートして使うことになる。
### App.vue
App.vueは、各ページのベース。ヘッダーやフッターなど、全ページに共通して表示させたいコンポーネントは、このファイルでインポートする。
この部分が、viewsフォルダ内の各ページ用のファイルを受け取って表示させる役割を担っています。
### main.js
全ページに反映させたいJavascriptコードを書くためのファイル。
### router.js
ルーティングの設定を行う際に編集するファイル。
## Vueファイル(.vue)の構成
- Vueファイルは `Template` `Script` `Style`の部品から成る
- http://www.code-magagine.com/?p=9961
### Template
- HTMLベースのテンプレート構文を記述する。
- HTML同様に各種タグを使用することが可能
- template内にはv-ifやv-forなど、Vue特有のレンダリング関数等の記述も可能。
### Script
- JS等のスクリプトを記述する(ファイルインポートもここで行う)
### Style
- CSSの記述を行うことが出来る
## Vueのインスタンス生成
- https://jp.vuejs.org/v2/guide/instance.html
- 全てのVueアプリケーションは`Vue`関数で新しいVue インスタンスを作成することによって起動される。
``` vue
var vm = new Vue({
// オプション
})
```
### コンポーネントについて
- https://jp.vuejs.org/v2/guide/components.html
- コンポーネントは名前付きの再利用可能な Vue インスタンス。
``` js
// button-counter と呼ばれる新しいコンポーネントを定義します
Vue.component('button-counter', {
data: function () {
return {
count: 0
}
},
template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
})
```
- 上記の場合、`<button-counter>`がコンポーネントとなる。
- コンポーネントを new Vue で作成されたルート Vue インスタンス内でカスタム要素として使用することが可能。
- 全ての Vue コンポーネントは Vue インスタンスで、同じオプションオブジェクトを受け入れる(いくつかのルート特有のオプションを除く)
- ヘッダー、サイドバー、およびコンテンツ領域のコンポーネントを一度に使用したい場合は Vue がそれらを認識できるように登録する必要がある。
- コンポーネント登録には、グローバルとローカルの2種類がある。
- グローバルに登録されたコンポーネントは、その後に作成されたルート Vue インスタンス(new Vue)のテンプレートで使用可能。
- さらに、その Vue インスタンスのコンポーネントツリーのすべてのサブコンポーネント内でも使用可能。
#### コンポーネントの命名規則
- コンポーネント名を定義する時、2 つの選択肢がある。
##### ケバブケース (kebab-case)
``` js
Vue.component('my-component-name', { /* ... */ })
```
##### パスカルケース (PascalCase)
``` js
Vue.component('MyComponentName', { /* ... */ })
```
- ケバブケースでコンポーネント名を定義する場合、そのカスタム要素を参照する時も同様に、ケバブケースを使用しなければならない。
- パスカルケースでコンポーネントを定義する場合、そのカスタム要素の参照には、どちらのケースも用いることが出来る。
- ただし、DOM 内 (すなわち、文字列でないテンプレート) に直接使用する場合には、**ケバブケース**の名前のみが有効。
#### グローバル登録・ローカル登録
- https://jp.vuejs.org/v2/guide/components-registration.html
- https://qiita.com/fumiya0414/items/84c677f256276aa99bf5
##### グローバル登録
- `Vue.component` だけを使ってコンポーネントを作成した場合、コンポーネントはグローバル登録されている。
- 登録後に作成された、全てのルート Vue インスタンス(new Vue)のテンプレート内で使用できることを意味する。
##### ローカル登録
- 特定のVueインスタンス配下でのみ利用するコンポーネントは、 ローカル登録によってスコープ(範囲)を狭めることが可能。
``` js
var ComponentA = { /* ... */ }
var ComponentB = { /* ... */ }
var ComponentC = { /* ... */ }
```
- 次に、components オプション内に使いたいコンポーネントを定義する
``` js
new Vue({
el: '#app',
components: {
'component-a': ComponentA,
'component-b': ComponentB
}
})
```
- components オブジェクトのそれぞれのプロパティは、キーはカスタム要素の名前になり、一方、値はコンポーネントのオプションオブジェクトを含む。
- ローカル登録されたコンポーネントは、他のサブコンポーネント内では使用できない。
### ルーティング
- https://jp.vuejs.org/v2/guide/routing.html
- `vue-router` を利用してルーティングを設定する
- https://mukai-lab.info/pages/tech/vue/vue2
#### ライフサイクル
- Vue.js には ライフサイクル という概念があり、Vue.js で作られたページはこのライフサイクルをもとに処理が実行されていく
- ライフサイクルを理解することで任意のタイミングで処理を実行させることが可能となる
- https://qiita.com/ksh-fthr/items/2a9f173c706ef6939f93
beforeCreate - インスタンスは生成されたがデータが初期化される前
created - インスタンスが生成され、且つデータが初期化された後
※beforeMount - インスタンスが DOM 要素にマウントされる前
※mounted - インスタンスが DOM 要素にマウントされた後
※beforeUpdate - データは更新されたが DOM に適用される前
※updated - データが更新され、且つ DOM に適用された後
※activated - 生き続けたコンポーネントが活性化するとき呼ばれる
※deactivated - 生存し続けたコンポーネントが非活性化されるとき呼ばれる
※beforeDestroy - Vue インスタンスが破壊される前
※destroyed - Vue インスタンスが破壊された後
※ サーバサイドレンダリングで呼ばれることはない
## 条件付きレンダリング
- 条件に応じて描画したい場合に使用される
- ブロックは、ディレクティブの式が真を返す場合のみ描画される
### v-if
```vue
<h1 v-if="awesome">Vue is awesome!</h1>
```
- `awesome`の評価が真の場合`Vue is awesome!`が描画される
#### v-else
```vue
<h1 v-if="awesome">Vue is awesome!</h1>
<h1 v-else>Oh no</h1>
```
- `awesome`の評価が真の場合`Vue is awesome!`が描画され、偽の場合は`Oh no`が描画される
#### v-else-if
```vue
<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else>
Not A/B
</div>
```
- 上記例の場合`type`がAの場合は`A`,Bの場合は`B`,どちらでもない場合は`Not A/B`と表示される
### v-show
- ほとんどv-ifと同様の記述でv-showというブロックを設定することが可能
```vue
<h1 v-show="ok">Hello!</h1>
```
- `ok`の評価が真の場合`Hello!`が描画される
#### v-ifとv-showの使い分けについて
- 頻繁に何かを切り替える必要があれば `v-show` を選ぶ。
- 条件が実行時に変更することがほとんどない場合は、`v-if` を選ぶ。
(v-showは非表示状態に関わらず内部的に描画準備は完了している状態で、v-ifは条件が成立するまで描画を行わないため。)
### v-for
- https://v3.ja.vuejs.org/guide/list.html
- 配列を複数回レンダリングすることが可能
```vue
<div v-for="item in items">
{{ item.text }}
</div>
```
- インデックスのエイリアスを指定することも可能
```vue
<div v-for="(item, index) in items"></div>
<div v-for="(value, key) in object"></div>
<div v-for="(value, name, index) in object"></div>
```
### v-if と v-for
- `v-if` と `v-for` 推奨されない
- 一緒に使用される場合は `v-for` の方が優先度が高くなる。
- 詳細な理由については以下を確認
- https://v3.ja.vuejs.org/style-guide/#v-for-%E3%81%A8%E4%B8%80%E7%B7%92%E3%81%AB-v-if-%E3%82%92%E4%BD%BF%E3%81%86%E3%81%AE%E3%82%92%E9%81%BF%E3%81%91%E3%82%8B-%E5%BF%85%E9%A0%88
### v-model
- form の input 要素 や textarea 要素、 select 要素に双方向 (two-way) データバインディングを作成するには、`v-model` を使用する。
``` vue
<input v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p>
```
### データのバリデーションについて
- https://jp.vuejs.org/v2/cookbook/form-validation.html
## 実際に作成しつつ覚える(Vue.js)
- 実際に作成しながら記述などを学習していく
https://blog.codecamp.jp/vuejs-helloworld-display
### プロジェクトの作成
1. (vue-cliをインストールして居ない場合のみ)
`npm install -g @vue/cli` を利用してインストール
1. `vue create <<project name>>`でVueプロジェクトを作成する
2. クリエイト後 `<<project name>>`フォルダに移動して `npm run serve`で起動する
### コンポーネント作成
`src/compornets/Tutorial.vue`を作成する
``` vue
<template>
<p>test</p>
</template>
<script>
export default {
name: 'Tutorial',
data () {}
}
</script>
```
### ルーティング設定
- `src/router/index.js`内のHelloWorld呼び出し箇所をTutorialへ変更する
```vue
import Vue from 'vue'
import Router from 'vue-router'
import Tutorial from '@/components/Tutorial'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'Tutorial',
component: Tutorial
}
]
})
```
### データバインディングの確認
- https://qiita.com/RINYU_DRVO/items/4c963e72ca0a0523b2fa
#### テキストのバインディング
- 二重波括弧 `{{ }}` で挟むことによってScriptで定義したテキストを取得することが可能
```vue
<template>
<div>
<span> Message: {{ msg }}</span>
</div>
</template>
<script>
export default {
data: function () {
return {
msg: "My name is msg"
}
}
}
</script>
```
#### HTMLのバインディング
- `v-html`を使用することによってHTMLのバインディングも可能となる
```vue
<template>
<div>
<p v-html="text"></p>
</div>
</template>
<script>
export default {
data: function() {
retrun {
text: 'Hello!'
}
}
</script>
```
#### 属性のバインディング
- https://jp.vuejs.org/v2/guide/class-and-style.html#%E9%85%8D%E5%88%97%E6%A7%8B%E6%96%87
```vue
<template>
<div v-bind:class="{ active: isActive }"></div>
</template>
<script>
export default {
data: {
isActive: true
}
}
</script>
```
上記のように設定した場合は下記のような出力結果となる
``` html
<div class="active"></div>
```
- 三項演算子も利用可能
```vue
<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>
```
- この場合 errorClass は常に適用されるが、activeClass クラスは isActive が真と評価されるときだけ適用される。
### イベントの購読(イベントハンドリング)
- https://jp.vuejs.org/v2/guide/events.html
- `v-on`を利用することでDOM イベントの購読、イベント発火時の JavaScript の実行が可能となる。
```vue
<div id="example-1">
<button v-on:click="counter += 1">Add 1</button>
<p>The button above has been clicked {{ counter }} times.</p>
</div>
```
```javascript
var example1 = new Vue({
el: '#example-1',
data: {
counter: 0
}
})
```
### 親子間のデータ受け渡し
- https://qiita.com/d0ne1s/items/f88ecd6aaa90c7bbc5d4
- プロパティはコンポーネントに登録できるカスタム属性。
- 値がプロパティ属性に渡されると、そのコンポーネントインスタンスのプロパティになる。ブログ投稿コンポーネントにタイトルを渡すには、 `props` オプションを使用して、コンポーネントが受け入れるプロパティのリストに含めることが可能
例:
``` javascript
Vue.component('blog-post', {
props: ['title'],
template: '<h3>{{ title }}</h3>'
})
```
- 上記のテンプレートでは、data と同様に、コンポーネントインスタンスでこの値にアクセスできる。
- プロパティが登録されると、次のようにそれをカスタム属性としてデータを渡すことが可能。
``` html
<blog-post title="My journey with Vue"></blog-post>
```
- `v-bind` を使って動的にプロパティを渡すことがも可能。
``` html
<blog-post
v-for="post in posts"
v-bind:key="post.id"
v-bind:title="post.title"
></blog-post>
```
### 子コンポーネントのイベントを購読する
- https://jp.vuejs.org/v2/guide/components.html#%E5%AD%90%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88%E3%81%AE%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%82%92%E8%B3%BC%E8%AA%AD%E3%81%99%E3%82%8B
- 親コンポーネントとやり取りする機能が必要がある場合、 `v-on` を使って子コンポーネントで起きた任意のイベントを購読することが可能。
例:親コンポーネントが `blog-post` という名前の場合
- ブログの投稿のテキストを拡大するためのアクセシビリティ機能を追加し、他のページのデフォルトのサイズにすることが可能。
- 親コンポーネントでは、`postFontSize` データプロパティを追加することでこの機能をサポートすることが可能
子コンポーネントの作成
``` js
new Vue({
el: '#blog-posts-events-demo',
data: {
posts: [/* ... */],
postFontSize: 1
}
})
```
親コンポーネントでのプロパティ追加
``` html
<blog-post
...
v-on:enlarge-text="postFontSize += 0.1"
></blog-post>
```
- 子コンポーネントでは、ビルトインの `$emit` メソッド にイベントの名前を渡して呼び出すことで、イベントを送り親コンポーネントがイベントを購読できる。
``` html
<button v-on:click="$emit('enlarge-text')">
Enlarge text
</button>
```
### Vue.jsでのルーティング設定(Router)
- Vueには公式でルーティングを行う [Vue-router](https://router.vuejs.org/)というライブラリがあるため基本的にはこのライブラリを使用する
- https://qiita.com/ksh-fthr/items/a4ac1d04d9923c550cd7
# Nuxt.jsとは
- https://digitalidentity.co.jp/blog/creative/javascript-nuxtjs.html
- Nuxt.js は Vue.jsのために作成されたフレームワーク
- 本プロジェクトはNuxt.jsで実装を行うため主にNuxt.jsの記法を学ぶ
## Vue.jsとの違い
- https://tech-parrot.com/vue/nuxt-vue-tigai/
- サーバーサイドレンダリングを行えるフレームワーク
- ファイルやフォルダ構造経由でコンフィギュレーションをセットすることができます。routerで逐一指示する必要がなくなり、慣れるととても便利
### サーバーサイドレンダリング(SSR)について
- https://blog.cloud-acct.com/posts/nuxtjs-server-side-rendering/
- ウェブページのレンダリングをブラウザの代わりにサーバー上で行う、画面の表示において有用なアプリケーションの機能
- 完全にレンダリングされたページをクライアントに送信する
- ページの初期表示が早くなることや、クローラビリティが向上するというメリットがある
### 自動ルーティング
- Nuxtにはファイル構成に応じて自動でルーティングをする機能がある
- pages ディレクトリにある Vue ファイルの構造に基づいて、vue-router の設定を自動的に生成する
- pages ディレクトリに .vue ファイルを作成すると、特別な設定をせずとも基本的なルーティングが動作する
- https://ja.nuxtjs.org/docs/2.x/features/file-system-routing
#### 異なるルーティングを独自に設定したい場合
- 上記の通り自動でルーティングする機能はあるが、独自のルーティングを設定したい場合はVue.jsと同様の方法を使用することでカスタムすることができる
- Nuxtにはvue-routerが標準で搭載されているため `nuxt.config.js`内で設定が可能
- https://ja.nuxtjs.org/docs/2.x/configuration-glossary/configuration-router
## Nuxt.jsのページ構成について
- Nuxt.jsは下記のような構成となる
```
sample
|- assets
|- components
|- layouts
|- middleware
|- node_modules
|- pages
|- plugins
|- static
|- store
|- nuxt.config.js
|- package.json
|- package-lock.json
README.md
```
### pages ディレクトリ
- アプリケーションのビューとルートが含まれている。
### components ディレクトリ
- componentsディレクトリにはページにインポートするすべての Vue.js のコンポーネントファイルを格納する。
### assets ディレクトリ
- スタイルや画像、フォントなどコンパイルされていないアセットを格納。
### static ディレクトリ
- 直接サーバのルートに配置される
- 名前を保持しなければいけないファイルもしくは変更されない可能性の高いファイルが含まれる。
### layouts ディレクトリ
- ComponentsファイルとPagesファイルのレイアウトを作成する
- VueではLayoutsの切り替えにはVue-router の「ネストされたルート」機能が必要
- https://router.vuejs.org/ja/guide/essentials/nested-routes.html
- https://qiita.com/yama-t/items/fde48aa128fe1a399726
### middleware ディレクトリ
- ページまたはレイアウトをレンダリングする前に実行できる、カスタム関数を定義することが出来る
### nuxt.config.js ファイル
- モジュールの追加やデフォルトの設定を上書きしたい場合にここを変更する。
## assets staticの用途の使い分けについて
- 基本的にはassetsを使用する
- Pagesの自動ルーティングとstatic内のファイル名称が一致すると直接URLを叩くとstaticのファイルにアクセス、Webページ内のリンクではルーティング先にアクセスするなど不整合が起きるためプロジェクトで使用ルールなどを決めた方が良い
- https://qiita.com/sohhprog/items/811adad4a9664bf810e0
### CSSの読み込みについて
#### 全体に影響するCSSの読み込み
- assets等のフォルダにCSSファイルを格納し `nuxt.config.js`ファイルに読み込むCSSを記述する
- https://qiita.com/kasyuu/items/ad186a2c20ae04ed79b2
#### 各ページ個別にCSSを読み込む場合
- ページごとに外部ファイルを読み込む場合は、pagesディレクトリのvueファイルで設定する
- https://qiita.com/TK-C/items/afaef4a4f0477c3be1e7
#### SCSS / SASS を読み込ませる場合
- SCSSの場合
- `vue-loader`を使用して読み込み設定を行う
- https://www.suzu6.net/posts/173-nuxt-scss/
- SASSの場合
- `sass` , `sass-loader` を利用して読み込み設定を行う
- https://ja.nuxtjs.org/docs/2.x/configuration-glossary/configuration-css
### 実際に作成する
1. Hello world作成
- `npx create-nuxt-app <project-name>` を使用して作成する
1. Component作成
- Header作成
- Components以下のフォルダに `Header.vue` を作成する
``` vue
<template>
<div class="header">
<h1>Header</h1>
<ul class="menu">
<li>メニュー</li>
<li>
<NuxtLink to="/">
Top
</NuxtLink>
</li>
</ul>
</div>
</template>
```
- Footerの作成
- Components以下のフォルダに `Footer.vue` を作成する
``` vue
<template>
<div class="footer">
サンプルフッタ
</div>
</template>
```
1. Layouts設定
- default.vueを作成して作成したHeader / Footerのコンポーネントをインポートする
``` vue
<template>
<div class="defaulttop">
<app-header />
<nuxt />
<app-footer />
</div>
</template>
<script>
import AppFooter from '~/components/Footer.vue' //フッターを読み込んでいる
import AppHeader from '~/components/Header.vue' //フッターを読み込んでいる
export default { //フッターを呼び出している
components: {
'app-footer':AppFooter,
'app-header':AppHeader
}
}
</script>
```
- default以外にもう一つHeaderだけをインポートしたLayoutsファイルの作成
``` vue
<template>
<div class="othertop">
<app-header />
<nuxt />
</div>
</template>
<script>
import Appheader from '~/components/Header.vue'
export default {
components: {
'app-header':Appheader
}
}
</script>
```
1. PagesへのImport
- Pagesフォルダの下に`index.vue` を作成
- Layoutsをインポートしない
``` vue
<template>
<section class="container">
<h2>Nuxt学習TOP</h2>
</section>
</template>
<script>
export default{
layout:'' // 記述しなくても問題なし
}
</script>
```
- Pagesフォルダの下に`notfotter.vue`を作成
- Layouts設定の項で作成したもう一つのLayoutファイルをインポートする
``` vue
<template>
<section class="container">
<h2>Nuxt学習notfotter</h2>
</section>
</template>
<script>
export default{
layout:'others'
}
</script>
```
1. Headerへ作成したPages以下のファイルのリンクを設定する
- `<Nuxtlink>`タグで実装
※ 外部へのリンクは通常のHTMLと同様に `a` タグにて実装する
# Vuexについて
- Vuexは、Vue.jsのために作成された状態管理用のライブラリ
- https://vuex.vuejs.org/ja/
## Vuexで実現出来ること
- 親子コンポーネント以外でデータや状態を保持することが可能
- https://reffect.co.jp/vue/understaind-vue-basic
### 実際に作成する
- 本学習ではNuxt.js向けの記法で学習を行う
- https://note.com/aliz/n/n6f4a42bce5b5
- Vue.js向けの記法は下記
- https://qiita.com/nmgw1119/items/27ed23e433ec54a9c950
1. ストア作成(state)
- stateはdataオプションのような存在で、stateが変更されるとコンポーネントの算出プロパティやテンプレートへと反映される。
これはVuexがVueのリアクティブシステムを活用して実装されている為
``` vue
export const state = () => ({
counter: 1,
})
```
2. ストアの参照
- 直接呼び出す場合は下記の通り `$store.state.~~` を使用する
``` vue
<template>
<div class="page">
<p>{{ $store.state.counter }}</p>
</div>
</template>
```
3. Gettersの利用
- 直接参照可能だが基本的にはGettersを使用して取得を行う
Store
``` vue
export const getters = {
counter (state) {
return state.counter
},
}
```
Vue
``` vue
<template>
<div class="page">
{{ counter }}
</div>
</template>
<script>
export default {
computed: {
counter () {
return this.$store.getters['counter']
},
}
}
</script>
```
4. ストアのデータ更新(mutations/actions)
- 値を更新は直接行わずに`mutations`を利用する
- 同期処理の場合はMutationsを利用し、非同期処理を行う場合はActionsを利用する
#### Mutations
Store
``` vue
export const state = () => ({
counter: 1,
})
export const getters = {
counter (state) {
return state.counter
},
}
export const mutations = {
countUp (state) {
state.counter++
},
}
```
Vue
``` vue
<template>
<div class="page">
<button
type="button"
@click="count"
>
{{ counter }}
</button>
</div>
</template>
<script>
export default {
computed: {
counter () {
return this.$store.getters['counter']
},
},
methods: {
count () {
return this.$store.commit('countUp')
},
},
}
</script>
```
#### Actions
Store
``` vue
export const state = () => ({
counter: 1,
})
export const getters = {
counter (state) {
return state.counter
},
}
export const actions = {
countAction ({ commit }) {
commit('countUp')
}
}
export const mutations = {
countUp (state) {
state.counter++
},
}
```
vue
``` vue
<template>
<div class="page">
<button
type="button"
@click="count"
>
{{ counter }}
</button>
</div>
</template>
<script>
export default {
computed: {
counter () {
return this.$store.getters['counter']
},
},
methods: {
count () {
return this.$store.dispatch('countAction')
},
},
}
</script>
```