1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2018-01-24

学習編

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

宣言的レンダリング

<!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側の記述です。
<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
<!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
<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
<!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
<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

<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番号は最初の6桁ほどがあれば大丈夫みたいです。
  • 今回は、そのまま次の記事に行きますので、戻しておきます。
  • git reflog で巻き戻しの履歴を確認します
  • git reset --hard d9b322

ユーザー入力の制御

  • index.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

<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
<!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
<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
<!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

<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
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

<!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

<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
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して終わります
  • 次回は、インスタンス編ですが 現時点でまだ書くかどうか決めていません(笑)。
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?