Vue.js勉強してみた　～オプションオブジェクト編～

急に始めます。

# Vueインスタンスの作成

``` js
new Vue({
  //オプション
});
```

# オプションオブジェクト
Vue関数には、オプションオブジェクトを書く。

！？
オプションオブジェクト？？
↓
### elオプション
Vueインスタンスを紐づけるDOM要素を指定。

``` js
new Vue({
  el: "#app"
});
```

### dataオプション

Vueインスタンスに持たせたいデータを登録。

``` js
new Vue({
  el: "#app"
  data: {
    message: "こんにちわ。Vue.jsさん"
  }
});
```

#### htmlでdataオプションを表示してみよう

```sample.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>title</title>
  </head>


  <body>
    <div id="app"> {{ message }} </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
    <script src="sample.js"></script>
  </body>
</html>
```

```sample.js
new Vue({
  el: "#app",
  data: {
    message: "こんにちわ。Vue.jsさん",
    url: "https://www.***.jp"
  }
});
```
![vue.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678701/cd9d9afd-c572-cbd8-f54f-0b16e2d5cdfc.png)
Vueで表示できた！

html中の{{}}は、マスタッシュ構文というみたい。
マスタッシュってなんかかっこいいけど、Mustacheってことで「口ひげ」の意味らしい。なんでかっていうと、{の形状が口ひげみたいだから。。。ってことみたい
。

VueインスタンスのデータはHTMLの属性値にも利用できる。
けど、マスタッシュ構文を使用することはできない。。

じゃどうするかっていうと、v-bindディレクティブを利用します！

は？ディレクティブって？

ディレクティブは、Vue.jsで使われる特別な属性のこと。
先頭に「v-」がつく。

使い方はこんなかんじ。

```js
<div id="app">
  <a v-bind:href="url">びゅー</a>
</div>
```

ほーほー。
class属性は、さらにオブジェクトと配列を指定できるみたい。

```js
new Vue({
  el: "#app",
  data: {
    isKoba: false,
    isOogaki: true,
    isSys: "new"
  }
});
```

```html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>title</title>
  </head>


  <body>
    <div id="app">
      <div v-bind:class="{ koba: isKoba, oogaki: isOogaki}"></div>
      <div v-bind:class="[isSys]"></div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
    <script src="sample.js"></script>
  </body>
</html>
```

レンダリング結果
![vue2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678701/4c600d19-a169-aba4-c360-65a3fd5880f7.png)

ふーん。
trueのisOogakiだけ付与されるってわけね。
ちなみに両方trueだと両方付与されるみたい。

ディレクティブについては、後半もうちょっと書きます。


### methodsオプション
Vueインスタンスは、メソッドを持たせることができる。
文章よりコードを見ればなんとなくわかるはず。

``` html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>title</title>
  </head>


  <body>
    <div id="app">
      <p>ぴえんカウント: {{ pien }} </p>
      <button v-on:click="addPien">ぴえん追加！</button>
      <p> 🥺  </p>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
    <script src="sample.js"></script>
  </body>
</html>
```

``` js
new Vue({
  el: "#app",
  data: {
    pien: 0
  },

  methods: {
    addPien: function(){
      this.pien = this.pien + 1
    }
  }
});
```

最初に気になるのはここだろう。
ぴえん　[WikiPedia](https://ja.wikipedia.org/wiki/%E3%81%B4%E3%81%88%E3%82%93)

まぁそれは良いとして、ボタンをクリックすると、「ぴえんカウント」が増えるってやつ。
やっぱり、「ぴえん」こえたら「ぱおん」したいので、v-ifディレクティブを使ってみよう。

``` html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>title</title>
  </head>


  <body>
    <div id="app">
      <p>ぴえんカウント: {{ pien }} </p>
      <button v-on:click="addPien">ぴえん追加！</button>
      <p> 🥺  </p>

      <p v-if="pien >= 10">ぴえんこえてぱおん！</p>
      <p v-else-if="pien >= 5">ぴえんこえて</p>
      <p v-else>ぴえん</p>

    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
    <script src="sample.js"></script>
  </body>
</html>
```
![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678701/7a9055d1-69b2-73ef-0ba7-8af57901c4c6.gif)


>全然話しずれるけど、windows10の標準機能で画面収録して、それをffmpegでgifにしてみた。

>``` 
># mp4を 横幅320、10fpsのgifに変換
>$ ffmpeg -i base_file.mp4 -vf scale=320:-1 -r 10 output.gif
>```


### computedオプション
算出プロパティです。
？

データを用いて算出した結果をプロパティとして扱えるようにした機能。

``` sample2.js
var app = new Vue({
  el: '#app',

  data: {
    firstName: 'tatsuya',
    lastName: 'kobayashi'
  },

  computed: {
    fullName: function(){
      return( '名前：' + this.lastName + this.firstName);
    }
  }
});
```

``` html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>title</title>
  </head>


  <body>
    <div id="app">
      <p> {{ fullName }} </p>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
    <script src="sample2.js"></script>
  </body>
</html>
```

プロパティ名でマスタッシュ構文に記述できる。

これぐらいなら良いけどもっと複雑になると、直接マスタッシュ構文内に記述するより、見やすくメンテナンスがあがるっていうわけ。

``` html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>title</title>
  </head>


  <body>
    <div id="app">
      <p> {{ '名前：' + lastName + firstName }} </p>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
    <script src="sample2.js"></script>
  </body>
</html>
```

>ん?メソッドでもいけそうな。使い分けが分からないなぁ。

ちなみに、methodsオプションだとこんな感じ。

``` sample3.js
var app = new Vue({
  el: '#app',

  data: {
    firstName: 'tatsuya',
    lastName: 'kobayashi'
  },

  methods: {
    fullName: function(){
      return( '名前：' + this.lastName + this.firstName);
    }
  }
});
```

``` html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>title</title>
  </head>


  <body>
    <div id="app">
      <p> {{ fullName() }} </p>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
    <script src="sample3.js"></script>
  </body>
</html>
```
マスタッシュ構文のところで()がつくんだね！
：
：
それだけ？

いいえ、computedの場合は結果がキャッシュされます。
なるほど。つまりどういうこと？

- methods・・・画面が更新される度
- computed・・・依存するデータが変更される度

``` html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>title</title>
  </head>


  <body>
    <div id="app">
      <input name="msg" type="text" v-model="msg">
      <p> {{ dateComputed }} </p>
      <p> {{ dateMethods() }} </p>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
    <script src="sample3.js"></script>
  </body>
</html>
```

``` sample3.js
var app = new Vue({
  el: '#app',

  data: {
    msg: 'test'
  },

  computed: {
    dateComputed: function(){
      return new Date()
    }
  },

  methods: {
    dateMethods: function(){
      return new Date()
    }
  }
});
```

![cash.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678701/f88bc73d-7607-d075-835f-f5a78a8859c5.png)

初期状態では同時刻となるが、テキストボックスの文字を変更すると、methodsだけが更新される。

![cash2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678701/5ecbcdb4-81f7-11f0-654e-17aab0f9b170.png)


じゃ、さっきの「computed・・・依存するデータが変更される度」っていう依存てどうするかっていうと。

``` js
var app = new Vue({
  el: '#app',

  data: {
    msg: 'test'
  },

  computed: {
    dateComputed: function(){
      const msg = this.msg
      return new Date()
    }
  },

  methods: {
    dateMethods: function(){
      return new Date()
    }
  }
});
```

例えばmsgプロパティの値をダミー変数に代入すれば、算出プロパティはmsgプロパティに依存するようになりおなじタイミングで更新される。


### this
ちょこちょこ出てるけどthisって。

オプションオブジェクト内では、オブジェクト自身を指す。
コールバック関数内では、windowsオブジェクトを参照しwindowsオブジェクトはmsgプロパティを持たないためundefinedでエラーとなる。

（thisは奥が深いと思うのでここではこれくらいにして、そうなんだくらいに思って前に進もう）