Vue.jsの使い方【まとめ】

この記事は「<a href="https://px.a8.net/svt/ejp?a8mat=35S4KG+EX13IQ+3L4M+BW8O2&a8ejpredirect=https%3A%2F%2Fwww.udemy.com%2Fcourse%2Fvue-js-complete-guide%2F" rel="nofollow">超Vue.js 2 完全パック - もう他の教材は買わなくてOK！</a><img border="0" width="1" height="1" src="https://www19.a8.net/0.gif?a8mat=35S4KG+EX13IQ+3L4M+BW8O2" alt="">」で学んだ内容を忘れない程度にメモしているものになります。

公式サイト：https://jp.vuejs.org/index.html

##コンポーネント
使い回す時に使う。

```
Vue.component()
```

###dataを関数にする必要がある理由
関数じゃなくてオブジェクトにしてしまうと、参照によって共有されてしまうから。
要するに、1つの値が変われば他の値も変わるような形になってしまう。
それは困るので、関数の中でreturnとして、初期値を返すようにしてあげる必要がある。
わからないなら`vue.jsの仕様だから`と考えてもOKかも。

###コンポーネントを使ったvueインスタンスの使い回し

```
[index.html]

<div id="app">
    <my-component></my-component>
    <my-component></my-component>
    <my-component></my-component>
</div>

-------------------
[index.js]

Vue.component('my-component',{
  data:function(){
    return{
      number:12
    }
  },
  template:'<p>いいね{{number}}</p>'
})

new Vue({
  el: '#app',
})
```

###ローカル登録

```
[index.html]

<div id="app">
    <my-component></my-component>
    <my-component></my-component>
    <my-component></my-component>
</div>

-------------------
[index.js]

var comopnent = {
  data:function(){
    return{
      number:12
    }
  },
  template:'<p>いいね{{number}}</p>'
})

new Vue({
  el: '#app',
  components:{
    'my-component':component
  }
})
```

###「 import App from ‘./App.vue'」の意味を理解する
vueファイルをimportしている。
componentのオブジェクトをインポートしている記述。

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

```
<template>
    <p>いいね{{number}}</p>
</template>

<script>
    export default {
        data: function(){
          return{
            number:5,
          };
        },
    }
</script>

```

##vueインスタンスについて
・vueインスタンスに最初からあるプロパティは、`$（ダラー）`をつけてアクセスする。（ユーザーが定義したプロパティと区別するためこのようになっている。）

###複数のvueインスタンスを作る

```

[index.html]

<div id="app1">
    <p>{{message}}</p>
</div>

<div id="app2">
    <p>{{message}}</p>
</div>

-------------------
[index.js]

new Vue({
  el: '#app1',
  data: {
    message:'インスタンス1',
  },
})

new Vue({
  el: '#app2',
  data: {
    message:'インスタンス2',
  },
})
```

###内部からvueインスタンスにアクセスする
`this`をつければOK。

```
var vm = new Vue({
  el: '#app1',
  data: {
    message:'インスタンス1',
  },
  computed:{
    instance:functino(){
      return this.data; ⇦ここ
    }
  }
})
```

###外部からvueインスタンスにアクセスする
・ただし、新しいプロパティ（リアクティブ）の追加は出来ない。
・「リアクティブでない」とはjsファイル側で変数を変更しても、viewファイル側の変数の値が変更されないこと。

```

[index.html]

<div id="app1">
    <p>{{message}}</p>
</div>

<div id="app2">
    <p>{{message}}</p>
</div>

-------------------
[index.js]

var vm = new Vue({
  el: '#app1',
  data: {
    message:'インスタンス1',
  },
})

vm.message = '書き換えられました。'

new Vue({
  el: '#app2',
  data: {
    message:'インスタンス2',
  },
})
```

##templateタグ
htmlとして表示されないけど、グループ化できる便利なやつ。
templateにはkey属性などを指定しても描画されないから無駄。

```
[index.html]

<div id="app">
  <template v-if="ok">
    <p>OK!1</p>
    <p>OK!2</p>
    <p>OK!3</p>
  </template>
</div>


-------------------
[index.js]

new Vue({
  el: '#app',
  data: {
    ok:true,
  },
})
```

##ディレクティブ
vue.jsにおける特別な属性。

###記法

```
v-○○
```

###v-once
一度だけしか描写したくない。（後からの処理によって変更されない。）

```
<p v-once> {{ once }} </p>
```

###v-html
エスケープされずに表示可能になる。
XSS脆弱性の危険。

```
<p v-html="html（プロパティ名）"></p>
```

###v-bind
htmlの属性にプロパティを入れたい時に使う。

```
<a v-bind:href="href">リンク</a>
以下省略形。
<a :href="href">リンク</a>
```

さらにオブジェクト型で記述もできる。

```
<a v-bind="{href:プロパティ,id:プロパティ}">リンク</a>
```

####【応用】クラスをデータにバインディング（紐付け）する。①
下記のようにすればクラスを動的に変換させられる。

```
[index.html]
<div id="app">
  <h1 :class="{red: isActive, 'bg-blue':!isActive}">Hello</h1>
  <button @click="isActive = !isActive">切り替え</button>
</div>


-------------------
[index.js]

new Vue({
  el:'#app',
  data:{
    isActive:true
  }
})
```

別の書き方

```
[index.html]
<div id="app">
  <h1 :class="classObject">Hello</h1>
  <button @click="isActive = !isActive">切り替え</button>
</div>


-------------------
[index.js]

new Vue({
  el:'#app',
  data:{
    isActive:true
  },
  computed:{
    classObject:function(){
      return{ 
        red: this.isActive,
        'bg-blue':!this.isActive}
    }
  }
})
```

####【応用】クラスをデータにバインディング（紐付け）する。②
それぞれ普通に動的にクラスを変化させる方法

```
[index.html]
<div id="app">
  <h1 :class="classObject">Hello</h1>
  <button @click="isActive = !isActive">切り替え</button>

  <h1 :class="[color,bg]">Hello</h1>
//下記のような表現も可能。
  <h1 :class="[{red:isActive},bg]">Hello</h1>
</div>


-------------------
[index.js]

new Vue({
  el:'#app',
  data:{
    isActive:true
    color:'red',
    bg:'bg-blue'
  },
  computed:{
    classObject:function(){
      return{ 
        red: this.isActive,
        'bg-blue':!this.isActive}
    }
  }
})
```

####style属性をオブジェクトを用いて動的にバインディングする

```
[index.html]
<div id="app">
  <h1 :style="{color:textColor, 'background-color':bgColor}">Hello</h1>
</div>


-------------------
[index.js]

new Vue({
  el:'#app',
  data:{
    isActive:true
    textColor:'red',
    bgColor:'bg-blue'
  },
})
```

もう少し綺麗な書き方。

```
[index.html]
<div id="app">
  <h1 :style="styleObject">Hello</h1>
</div>


-------------------
[index.js]

new Vue({
  el:'#app',
  data:{
    isActive:true
    styleObject:{
      color:'red', 
      'background-color':'blue'}
  },
})
```

####複数のスタイルオブジェクトを配列でまとめる

```
[index.html]
<div id="app">
  <h1 :style="[styleObject,baseStyles]">Hello</h1>
</div>


-------------------
[index.js]

new Vue({
  el:'#app',
  data:{
    isActive:true
    styleObject:{
      color:'red', 
      'background-color':'blue'
    }
    baseStyles:{
      fontSize:'60px'
    }
  },
})
```

###v-on
DOMが変化した時に処理を実行したい時に使える。

```
[index.html]

//クリックはイベント名を指定すればOK。（例：hover）
<div id="app">
<button v-on:click="n += 1（処理を書く）"></button>
</div>

あるいは

<div id="app">
//（）は省略可
<button v-on:click="countUp()"></button>
</div>

省略形
<div id="app">
<button @click="countUp()"></button>
</div>

-------------------
[index.js]

new Vue({
  el:'#app',
  data:{
    number:0
  },
  methods:{
    countUp:function(){
      this.number +=1
      }
    }
})
```

###v-if,v-else-if,v-else
条件レンタリングに使う。

```
[index.html]

<div id="app">
  <p v-if="ok">OK!</p>
  <p v-else-if="maybeOk">maybeOk</p>
  <p v-else>OK!</p>
</div>


-------------------
[index.js]

new Vue({
  el: '#app',
  data: {
    ok:true,
    maybeOk:true
  },
})
```

###v-show
'v-if'と同じような機能。ただし、こちらは要素を完全に消し去るのではない。
style属性のdisplayをnoneにするだけ。
初期描画が遅い。
ifの場合は頻繁に消したりつけたりする時に遅くなる。
**つまり、何でも切り替える処理は'v-show'を使うのが良き良き** 

###v-for
配列を1つずつ処理する。
key属性も必ずつける。

```
[index.html]

<div id="app">
  <ul>
    <li v-for="fruit in fruits" :key="fruit">{{fruit}}</p>
  </ul>
</div>


-------------------
[index.js]

new Vue({
  el: '#app',
  data: {
    fruits:['りんご','バナナ','ぶどう' ],
  },
})
```

```
[index.html]

<div id="app">
  <ul>
    <li v-for="fruit in fruits">{{fruit}}</p>
  </ul>
</div>


-------------------
[index.js]

new Vue({
  el: '#app',
  data: {
    fruits:['りんご','バナナ','ぶどう' ],
  },
})
```

####インデックスを指定する場合。

```
<li v-for="(fruit,index) in fruits">{{index}}:{{fruit}}</p>
```

####オブジェクトの場合。
第一引数：値
第二引数：キー
第三引数：インデックス

```
<li v-for="(value,key,index) in object">{{index}}:{{key}}-{{value}}</p>

-------------------
[index.js]

new Vue({
  el: '#app',
  data: {
    object:{
      firstName:'太郎',
      lastName:'山田',
      age:21
  },
})
```

####数値の場合。

```
<li v-for="n in 100">{{n}}</p>
```

####inではなくofにもできる

```
<li v-for="n of 100">{{n}}</p>
````

####イベントオブジェクトの取得

```
[index.html]

<div id="app">
  <p id="sampleText" v-on:mousemove="mousePosition">ここにマウスを載せると下のX、Yの値が変わるよ</p>
  <p id="result">X:{{x}}, Y:{{y}}</p>
</div>


-------------------
[index.js]

new Vue({
  el: '#app',
  data: {
    x: 0,
    y: 0
  },
  methods: {
    mousePosition: function(event) {
      this.x = event.clientX;
      this.y = event.clientY;
      // eventの中を見てみると、全てのイベントオブジェクトが入っている
      console.log(event);
    }
  }
})

```

参考：[Vue.jsでイベントオブジェクトを取得する](https://qiita.com/hidache/items/445cf682f50a88dc57be)

####引数を与える

イベントオブジェクトを使いたい時は`$event`を使う。

```
[index.html]

<div id="app">
  <p id="sampleText" v-on:mousemove="mousePosition($event,10)">ここにマウスを載せると下のX、Yの値が変わるよ</p>
  <p id="result">X:{{x}}, Y:{{y}}</p>
</div>


-------------------
[index.js]

new Vue({
  el: '#app',
  data: {
    x: 0,
    y: 0
  },
  methods: {
    mousePosition: function(event,hikisu) {
      this.x = event.clientX / hikisu;
      this.y = event.clientY / hikisu;
      // eventの中を見てみると、全てのイベントオブジェクトが入っている
      console.log(event);
    }
  }
})

```

###v-model
双方向バインディングを使用するためのディレクティブ。

```
[index.html]

<div id="app">
  <input type="text" v-model="message">
  <p>{{message}}</p>
</div>


-------------------
[index.js]

new Vue({
  el: '#app',
  data: {
    message:'こんにちは'
  },
})

```

##イベント修飾子

###.stop
伝播させないようにする。

```
<p id="sampleText" v-on:mousemove.stop>ここにマウスを載せると下のX、Yの値が変わるよ</p>
```

###prevent
リンクなどをクリックしても反応しなくなる。

##キー修飾子
特定のキーの時のみ反応させる。
沢山ある。

例えば、エンターキーを押した時は下記の通り。

```
<input type="text" v-on:keyup.enter="メソッド名">

//繋げられる
<input type="text" v-on:keyup.enter.space="メソッド名">
```

##あんまり使わないけど、知っておくと良いやつ
あんまり使わないけど、たまに出てきたりするやつについてまとめておきます。（ただ、分類が面倒かっただけというのは内緒で。笑）

###$mountメソッド
elプロパティの代わりにできる。
使い方は`インスタンス.mount`という感じ。

```
vm.$mount(#app)
```

###templateプロパティ
vueインスタンス内にhtmlを書く時に使える。

下記のように書けば`#app`に`こんにちは`と表示される。

```
new Vue({
  el: '#app',
  data: {
    message:'こんにちは'
  },
  template:'<h1>こんにちは</h1>'　⇦ポイント
})

//書き換え
new Vue({
  data: {
    message:'こんにちは'
  },
  template:'<h1>こんにちは</h1>'
}).$mount('#app') ⇦ポイント
```

###render関数
・使う理由としては、本来のDOMをいちいち変更（ブラウザにアクセス）のは時間がかかる（処理が遅い）ので、render関数（仮想DOM）を使う。
・DOM要素を作るものでは無い。仮想DOM（VNODE：ブイノード）を作る。
・要するにJavaScriptのオブジェクトをDOMっぽくしている。
・JavaScriptの`createElementメソッド`とは別。

```
new Vue({
  el: '#app',
  data: {
    message:'こんにちは'
  },
  render:function(createElement){
    return createElement('h1','こんにちは', + this.name) ⇦ポイント
})

//書き換え（引数の名前は何でも良い：hにすることが多いらしい。）
render:function(h){
    return h('h1','こんにちは', + this.name) ⇦ポイント
})
```

##知識的な部分
・dataには動的プロパティは使わない。基本的にプロパティの初期値をつけるもの。
・動的なプロパティを使いたい場合は`computed`をつかう。
・watchはあまり使わないけど、`computed`が庇いきれない部分（非同期の時など）に使う。
・JavaScriptのキー名にケバブケース（ハイフンで単語を区切るやつ）がきたときは、''（シングルクォート）で囲む必要がある。
・v-forの時にはkeyを指定すると予期せぬバグを防ぐことに繋がる。
・templateにはkey属性などを指定しても描画されないから無駄。
・リアクティブのプロパティを作るためには最初にdata{}内にプロパティを設定しておく必要がある。
→なぜならvue.jsはdata内のプロパティにsetterとgetterを設置しているから。
・DOMを変更（ブラウザにアクセス）するのは処理が遅いので、仮想DOMを使う方が良い。

###（）をつけるタイミング
・computedプロパティはつけない
・{{}}の中身にメソッドを書くときは必要
・{{}}外でメソッドを書くときは不要