学習編
- 前回の環境編でせっかく作った環境ですので、それを使って学習していきたいと思います。
宣言的レンダリング
-
バインディングの辺りから始めます.
-
index.html - 今後、この記載は、simpleHtmlの記載内容と思ってください。
<!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して終わります
- 次回は、インスタンス編ですが 現時点でまだ書くかどうか決めていません(笑)。