dotinstall で勉強している初心者がVue.jsの公式ガイドを勉強するメモ 宣言的レンダリング編

# 学習編
* 前回の環境編でせっかく作った環境ですので、それを使って学習していきたいと思います。

## 宣言的レンダリング
* バインディングの辺りから始めます.
* https://jp.vuejs.org/v2/guide/index.html

*  index.html  - 今後、この記載は、simpleHtmlの記載内容と思ってください。

``` html
<!DOCTYPE html>
<html>
<head>
  <title>Welcome to Vue</title>
  <script src="https://unpkg.com/vue"></script>
</head>
<body>
  <div id="app">
    <span v-bind:title="message">
       Hober ....
    </span>
  </div>

  <script>
    var app = new Vue({
      el: '#app',
      data: {
        message: 'You loaded this page on ' + new Date().toLocaleString()
      },
      methods: {
      }
    })
  </script>
</body>
</html>
```
* リロードは手動で行なってください。
* 画面に表示されている Hover..が表示されていますが、見る場所はconsole側です。
* Elementsを開き、spanタグのtitle属性がリアクテブになっているのかを確認します。
* ブラウザーのコンソールで確認します。
  - app.message = 'some new message'  // 記述は若干違います
  - title属性が書き換わっているのが確認出来たのでokです。


### node側
* App.vue   - 今後この記述は、node側の記述です。

``` html
<template lang="pug">
  #App
    span(v-bind:title="message") Hober.....
</template>

<script>
export default {
  name: 'app',
  data () {
    return {
      message: 'You loaded this page on ' + new Date().toLocaleString()
    }
  }
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
h1, h2 {
  font-weight: normal;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>


```
* こちらは、オートリロードで便利ですね。
* こちらも、ブラウザーのコンソールで確認してみますが。。。
  - app.message = 'some new message'ではないですね。。。 参照エラーですね
* App.setAttribute('title','some new message')　でtitleを書き換えできますが、これは本来の趣旨と違うんでしょうね。
* わかる方教えてもらえると助かります。 Question　01


## 条件分岐とループ
* index.html

``` html
<!DOCTYPE html>
<html>
<head>
  <title>Welcome to Vue</title>
  <script src="https://unpkg.com/vue"></script>
</head>
<body>
  <div id="app">
   <span v-if="seen">Now you see me</span>
  </div>

  <script>
    var app = new Vue({
      el: '#app',
      data: {
        seen: true
      },
      methods: {
      }
    })
  </script>
</body>
</html>
```
* ブラウザーコンソールでapp.seen = falseと叩くと、spanタグ自体が無くなっているので、OKですね。

## node側
* App.vue

``` html
<template lang="pug">
  #app
    button(v-on:click="seen = !seen") toggle
    div(v-if="seen") Now you see me
</template>

<script>
export default {
  name: 'app',
  data () {
    return {
      seen: false,

    }
  }
}
</script>

<style lang="scss">
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
h1, h2 {
  font-weight: normal;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>

```
* コンソールで書き換えがわからないので、違う方法で確認してみます。
*  ここでは、ボタンで true / false を切り替えて見ます。
*  seen　の値で、v-if が切り替わっているのがわかります。
  - ここでは、div属性自体が無くなっていることもブラウザーのデベロッパーツールで確認して見てください。
  


### v-for

* index.html

``` html
<!DOCTYPE html>
<html>
<head>
  <title>Welcome to Vue</title>
  <script src="https://unpkg.com/vue"></script>
</head>
<body>
  <div id="app">
    <ol>
      <li v-for="todo in todos">
        {{ todo.text }}
      </li>
    </ol>
  </div>

  <script>
    var app = new Vue({
      el: '#app',
      data: {
        todos: [
          { text: 'Learn JavaScript' },
          { text: 'Learn Vue' },
          { text: 'Build something awesome' }
        ]
      },
      methods: {
      }
    })
  </script>
</body>
</html>
```
* コンソールで追加もしてみます。
  - app.todos.push({text: 'new item'})
  - 追加されているので、OKです。

### node
* App.vue

``` html
<template lang="pug">
  #App
    ol
      li(v-for="todo in todos") {{ todo.text }}
</template>

<script>

export default {
  name: 'app',
  data () {
    return {
      todos: [
        { text: 'Learn JavaScript' },
        { text: 'Learn Vue' },
        { text: 'Build something awesome' }
      ]
    }
  }
}


</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
h1, h2 {
  font-weight: normal;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  /* display: inline-block; */
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>
```
* こちらも、表示されているのでOKです。
* リアクティブ確認の追加は、buttonで追加してみます。

* App.vue

``` html
<template lang="pug">
  #app
    button(v-on:click="todos.push({ text: 'new item' })") 追加
    ol
     li(v-for="todo in todos")
       | {{ todo.text }}
</template>

<script>
export default {
  name: 'app',
  data () {
    return {
      todos: [
        { text: 'Learn JavaScript' },
        { text: 'Learn Vue' },
        { text: 'Build something awesome' }
      ]
    }
  }
}
</script>

<style lang="scss">
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
h1, h2 {
  font-weight: normal;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>


```

* ボタンで追加されているのがブラウザーで確認できるのでOKですね。
* 
#### 次に行く前に、両環境ともGitコミットしておきましょう

* atomでコミットするほうが簡単ですがターミナルでコミットしておきます。
* git add .
* git commit -m "v-forまで完了"
* もう一度最初のコミット位置から勉強するには、コミットを巻き戻します.
* git log でコミット一覧を確認します。

```
commit d9b322b983728c3f012d3a8474973309d72184b4
Date:   Wed Jan 24 16:44:52 2018 +0900
    v-forまで完了

commit 6177e20641048db29f582adf4bf8ec8cada4f01a
Date:   Wed Jan 24 01:37:40 2018 +0900
    first

```

* 最初のコミットまで巻き戻します.
* git reset --hard 6177e20641048db29f582adf4bf8ec8cada4f01a
  - 尚commit番号は最初の６桁ほどがあれば大丈夫みたいです。
* 今回は、そのまま次の記事に行きますので、戻しておきます。
* git reflog で巻き戻しの履歴を確認します
* git reset --hard d9b322

## ユーザー入力の制御

* index.html

``` html
<!DOCTYPE html>
<html>
<head>
  <title>Welcome to Vue</title>
  <script src="https://unpkg.com/vue"></script>
</head>
<body>
  <div id="app">
    <p>{{ message }}</p>
    <button v-on:click="reverseMessage">Reverse Message</button>
  </div>

  <script>
    var app = new Vue({
      el: '#app',
      data: {
        message: 'Hello Vue'
      },
      methods: {
        reverseMessage () {
          this.message = this.message.split('').reverse().join('')
        }
      }
    })
  </script>
</body>
</html>
```

* ボタンを押すと関数が走り、messageの値を書き換えて、書き換わったmessageをVueが検知して、画面描画をしている感じですかね。

* App.vue

``` html
<template lang="pug">
  #App
    p {{ message }}
    button(v-on:click="reverseMessage") Reverse Message
</template>

<script>

export default {
  name: 'app',
  data () {
    return {
      message: 'Hello Vue'
    }
  },
  methods: {
    reverseMessage () {
      this.message = this.message.split('').reverse().join('')
    }
  }
}


</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
h1, h2 {
  font-weight: normal;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  /* display: inline-block; */
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>
```

* こちらも、問題なく動いていますね。

#### v-model

* index.html

``` html
<!DOCTYPE html>
<html>
<head>
  <title>Welcome to Vue</title>
  <script src="https://unpkg.com/vue"></script>
</head>
<body>
  <div id="app">
    <input type="text" v-model="message"/>
    <p>{{ message }}</p>
  </div>

  <script>
    var app = new Vue({
      el: '#app',
      data: {
        message: 'Hello Vue'
      },
      methods: {
      }
    })
  </script>
</body>
</html>
```

* App.vue

``` html
<template lang="pug">
  #App
    input(v-model="message")
    p {{ message }}
</template>

<script>

export default {
  name: 'app',
  data () {
    return {
      message: 'Hello Vue'
    }
  },
  methods: {
  }
}

</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
h1, h2 {
  font-weight: normal;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  /* display: inline-block; */
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>
```

* input など特定のときしか使えないみたいですが、Vueなら簡単にできますよ。　みたいな感じの機能ですね。
* 次に行く前に、必要ならバックアップ(commit)しておいてください。

## コンポーネントによる構成

* index.html

``` html
<!DOCTYPE html>
<html>
<head>
  <title>Welcome to Vue</title>
  <script src="https://unpkg.com/vue"></script>
</head>
<body>
  <div id="app">
    <ol>
      <todo-item></todo-item>
      <todo-item></todo-item>
      <todo-item></todo-item>
    </ol>
  </div>

  <script>
    Vue.component('todo-item', {
      template: '<li>This is a todo</li>'
    })
    var app = new Vue({
      el: '#app',
      data: {
      },
      methods: {
      }
    })
  </script>
</body>
</html>

```

* 独自タグで書けるようになるみたいですね。

* App.vue

``` html
<template lang="pug">
  #App
    ol
      todo-item
      todo-item
      todo-item
</template>

<script>

export default {
  name: 'app',
  data () {
    return {
      message: 'Hello Vue'
    }
  },
  methods: {
  }
}

</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
h1, h2 {
  font-weight: normal;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  /* display: inline-block; */
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>
```
* main.js

``` js
import Vue from 'vue'
import App from './App.vue'


Vue.component('todo-item', {
  template: '<li>This is a todo</li>'
})

 new Vue({
  el: '#app',
  render: h => h(App)
})
```

* component はどこに書くのがいいのか迷いました。　とりあえず、jsの元締めである、main.jsに書きました。
* いい場所がみつかったら、その時移動します。

### props
* componentへの値の引き渡しの為に利用するみたいです。

* index.html

``` html
<!DOCTYPE html>
<html>
<head>
  <title>Welcome to Vue</title>
  <script src="https://unpkg.com/vue"></script>
</head>
<body>
  <div id="app">
    <ol>
      <todo-item v-for="item in list" v-bind:todo='item'></todo-item>
    </ol>
  </div>

  <script>

    Vue.component('todo-item', {
      props: ['todo'],
      template: '<li>{{ todo.text }}</li>'
    })
    var app = new Vue({
      el: '#app',
      data: {
        list: [
          { id: 0, text: 'Vegetables' },
          { id: 1, text: 'Cheese' },
          { id: 2, text: 'Whatever else humans are supposed to eat' }
        ]
      },
      methods: {
      }
    })
  </script>
</body>
</html>
```

* v-for と v-bind　のあわせ技ですね。　違いはv-bindの行き先が,appのdataではなく、componentのpropsであるtodoになるところですね。

* App.vue

``` html
<template lang="pug">
  #App
    ol
      todo-item(v-for="item in list" v-bind:todo="item")
</template>

<script>

export default {
  name: 'app',
  data () {
    return {
        list: [
          { id: 0, text: 'Vegetables' },
          { id: 1, text: 'Cheese' },
          { id: 2, text: 'Whatever else humans are supposed to eat' }
        ]
    }
  },
  methods: {
  }
}

</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
h1, h2 {
  font-weight: normal;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  /* display: inline-block; */
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>
```

* main.js

``` js
import Vue from 'vue'
import App from './App.vue'


Vue.component('todo-item', {
  props: ['todo'],
  template: '<li>{{ todo.text }}</li>'
})

 new Vue({
  el: '#app',
  render: h => h(App)
})
```

* componentを書いている場所が違うだけで、内容は一緒です。
* 初心者向け同士なので、抜き出さず全掲載していますが、どこを書き換えているかわかりづらいですね。　どうしたら、わかりやすく書けるのか慣れないと難しいです。
* atomの拡張パッケージである,split-diffを入れると、見比べできるので違いがわかりやすいです。　重宝してます
* とりあえず、変化の少ないstyleタグは、次回から省略して掲載していきます。
* 今回は、ここで終了です。　git commitして終わります
* 次回は、インスタンス編ですが　現時点でまだ書くかどうか決めていません（笑）。