Vue.jsの基本　超メモ　Part 1

僕はRailsでポートフォリオ作成中で、Vue.jsを導入しているところです。

備忘録的にVueの構文、書き方をメモしていきます。


#Vue.js 基本の形


```html
<body>
  <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>



    <div id="app">
      <p> 私は{{ name }}</p>
    </div>
   
   
   
  <script>
    
    new Vue({
      el: '#app',
      data: {
        name: "ヨネスケ",
      }
    })
    
  </script>
</body>
```

divタグ内はテンプレートと呼ばれる。

ここのテンプレートをscriptタグで指定して、様々な処理を書き、テンプレートで描写する。


上のコードをブラウザで確認すると
```私はヨネスケ```

と表示される。


#テンプレート　
 
```html
　<div id="app">
　　<p>{{ name }}</p>
 </div>
```


#｛｛　｝｝？

Vueではこの二重波括弧を使ってデータを画面にレンダリングできる。

<h3>基本</h3>

```html
<p>はじめまして。{{ name }}です。</p>
```
二重波括弧を使って「はじめまして。ヨネスケです。」とレンダリングする。


<h3>式を使う</h3>

```html
<p>えんぴつは{{ price + ５ }}円です。</p>
```
単純な式を使ってデータを操作して、レンダリングもできる。

<h3>三項演算子を使った式展開</h3>

```html
<p>僕は{{age > 20 ? '成人しています' : '未成年です'}}っ！！</p>
```


<h3>注意</h3>
単一の式以外は書けない

```html
<p>{{ let i = 0 }}</p>
```

みたいなのは書けない。




#Vueインスタンス


```js

new Vue(｛
 el: '#app',
 data{
  name: "ヨネスケ"
 }
｝)
```


<h3>new Vue</h3>

Vueインスタンスを宣言している。
「Vueを使うぞ！！」ということ。


<h3>el</h3>
elementのこと。
どこの要素を対象にしているかを指定している。
※ $mountを使い指定することもできる

<h3>data</h3>
dataは要素の中にデータをもたせる。
例でいうと```name="ヨネスケ"```がデータ。

文字列や数字、Booleanなど持たせられる
インスタンス外で定義したオブジェクトを渡すことも可能。

```JS
var data = {
 message: "こんばんわ"
 time: 17
 name: "ヨネスケ"
 hunger: true

}

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


```


<h3>methods</h3>
関数も用意できる

```html
<body>


 <div id="app">
　　<p>{{ message }}</p>
   <p>{{ sayTotugeki() }}</p>
 </div>

</body>

<script>

new Vue({
 el: '#app',
 data:{
  message: "こんばんわ"
 }, 
 methods:{
  sayTotugeki:function(){
   return '突撃!　となりの晩ごはん';
  }
 }
})

</script>

```

<h3>computed 算出プロパティ</h3>
動的なプロパティを使うときに用いる。


```html
<body>
  <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>



    <div id="app">
      <p> 私は{{ name }}</p>
      <p> 今、{{ time }} 時</p>
      <p>{{ heThoughts }}</p>
   
      <button @click = "time += 1">時をすすめる</button>
    </div>
   
   
   
  <script>
    
    new Vue({
      el: '#app',
      data: {
        name: "ヨネスケ",
        time: 12
      },
      computed:{
        heThoughts: function(){
          return this.time > 16 ? '突撃！　隣の晩ごはん' : '晩ごはん作るのメンドイ'
        }
      }
    })
    
  </script>
</body>

```


もちろんこの動作自体はmethodsでも実装可能。

```html
<body>
  <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>



    <div id="app">
      <p> 私は{{ name }}</p>
      <p> 今、{{ time }} 時</p>
      <p>{{ heThoughts() }}</p>
   
      <button @click = "time += 1">時をすすめる</button>
    </div>
   
   
   
   <script>
    
    new Vue({
      el: '#app',
      data: {
        name: "ヨネスケ",
        time: 12
      },
      methods:{
        heThoughts: function(){
          return this.time > 16 ? '突撃！　隣の晩ごはん' : '晩ごはん作るのメンドイ'
        }
      }
    })
    
  </script>
</body>

```

このように同じ動作は実装できる

<h3>computedとmethodsの違いは？</h3>
```<p> {{ heThoughts( ) }} </p> ```のように二重波括弧内にmethodsを書くと、テンプレート内で変化があれば毎回、実行されてしまう。
同じテンプレート内の全く関係無い動的なプロパティが変化しても、実行されてしまう。


<strong>computedプロパティはプロパティ内にある参照先。今回で言うところの```this.time```に変化があった時のみ実行される。







#インスタンス外部からインスタンス内のデータやメソッドにアクセスする場合はどうするのか？

vueインスタンスを変数に代入することで外部からアクセスが可能になる。

```html

<body>
  <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>



    <div id="app">
      <p> 私は{{ name }}</p>
      <p> 今、{{ time }} 時</p>
      <p>{{ heThoughts() }}</p>
   
      <button @click = "time += 1">時をすすめる</button>
    </div>
   
   
<script>
var vm1 = new Vue({
 el: '#app1',
 data: {
  message: "New Vue 1 ! "
 }
})


vm1.message = "外部からアクセスできた！"


var vm2 = new Vue({
 el: '#app2',
 data: {
  message: "New Vue 2 ! ",
  methods:{
   changeMessage1: function(){
    vm1.messge =  'Vue2からアクセスしました。'
   }
  }
 }
})

</script>

</body>
```

※外部からdataを追加することもできるが、それはリアクティブにならない。
初期表示はできるが、クリックイベントなどで内容を変更することはできない。


#同じインスタンスのメソッドやデータにアクセスするには？

外部からアクセスする際はインスタンスを変数に代入して、```vm.message```や```vm.$data```としていた。

同じインスタンス内のdataやmethodsにアクセスするにはどうすればいいか？

<strong>```this```を使う

```JS
new Vue({
 el: '#app1'
 data: {
  message: "New Vue "
 }
 computed{
  myData: function(){
   return this.$data
  }
 }
})
```

---



#テンプレートの書き方　亜種

基本的なテンプレートの書き方は

```html
　<div id="app">
　　<p>{{ message }}</p>
 </div>
```

であるが、その他にも２パターンある。

<h3>template</h3>

```html
<!-- いつもの書き方 -->
　<div id="app">
　　<p>{{ message }}</p>
 </div>

<script>
 new Vue({
  
  el: '#app',
  data:{
   message: "こんにちわ"
  },  
 
 })
</script>




<!-- template -->

　<div id="app"> </div>

<script>
 new Vue({
  
  el: '#app',
  data:{
   message: "こんにちわ"
  },  
  template: '<p>{{ message }}</p>'
 
 })
</script>

```

htmlコードをそのまま文字列に入れる形なので、見づらい。あまり使う機会はなさそう。


<h3>render関数</h3>

```html
<!-- いつもの書き方 -->
　<div id="app">
　　<p>{{ message }}</p>
 </div>

<script>
 new Vue({
  
  el: '#app',
  data:{
   message: "こんにちわ"
  }
 })

</script>




<!-- render関数 -->

<div id="app"> </div>

<script>
 new Vue({
  
  el: '#app',  
  render: function(createElement){
    return createElement('p', 'こんにちわ');
  },
 })

// h でも書ける //

new Vue({
  
  el: '#app',  
  render: function(h){
    return h('p', 'こんにちわ');
  },
 })
</script>

```

createElemet（ ｈ で表現されることもある）は仮想DOMのために、仮想ノード（VNode）を返している


<h3>どの書き方も最終的には仮想ノードになる</h3>
基本的な書き方も、templateも最終的にはVueインスタンスが作られたときにrender関数に変換されている。

どのような形でも最終的には仮想ノードを返している。

仮想ノードで仮想的なDOMを作っていて、最終的にDOMツリーに反映させている。


#仮想DOMとは？
<h3>実質的なDOM</h3>
「Document Object Model」を操作することでJavaScriptからHTMLを変更し、web上の見た目や変化を可能にする。

DOMツリーへの直接的な操作（参照、作成、修正、削除）は時間がかかる。

画面上で変化が起きる度に実質的なDOMをすべて読み込みなおして、再構築しているため、変化が多ければ時間がかかる。

<h3>仮想DOM</h3>
仮想DOMとは```実質的なDOMを模したJavaScripｔのオブジェクト。```

変化が多くなっても、JavaScriptオブジェクトとして、【変化前】と【変化後】仮想DOMの２つを作り、差分だけ実質的なDOMに反映させる。

<strong>そのため描写の速度が非常に早い