前章
v-onでイベント処理を使いこなす
v-on:click="メソッド名"
とすることで任意のメソッドをクリック時に発動できる
<!-- HTML -->
<div id="hoge">
<button v-on:click="hogeck">ホゲるボタン</button>
<p>{{ message}}</p>
</div>
<!-- HTML -->
<!-- Vue -->
<script>
var app = new Vue({
el: '#hoge',
data: {
message: 'まだホゲってない'
},
methods: {
hogeck: function(){
this.message = 'ほげぇぇぇぇぇぇぇぇ'
}
},
})
</script>
<!-- Vue -->
また、v-on:click
は@click
と省略できる
<button v-on:click="hogeck">ホゲるボタン</button>
<button @click="hogeck">ホゲるボタン</button>
引数について
引数の渡し方
<!-- HTML -->
<div id="hoge">
<button @click="hogeck('ほげええええええ')">ホゲるボタン</button>
</div>
<!-- HTML -->
<!-- Vue -->
<script>
var app = new Vue({
el: '#hoge',
methods: {
hogeck: function(message){
alert(message) // ホゲるボタン
}
},
})
</script>
<!-- Vue -->
イベントオブジェクト
イベントオブジェクトとは、その名の通りイベントに関する情報を管理しているオブジェクトになる
function(arg_event)
としてやることで(引数名はなんでも良い。暫定的にarg_event
としている)、arg_event
にイベントオブジェクトが格納される。
<!-- HTML -->
<div id="hoge">
<button @click="hogeck">ホゲるボタン</button>
</div>
<!-- HTML -->
<!-- Vue -->
<script>
var app = new Vue({
el: '#hoge',
methods: {
hogeck: function(arg_event){
alert(arg_event.target.textContent) // ホゲるボタン
}
},
})
</script>
<!-- Vue -->
イベントオブジェクトと引数を同時に受け取る場合
メソッドの第二引数に$event
を入れてやることで取得可能。
$event以外の名前では動作しないので注意
<!-- HTML -->
<div id="hoge">
<button @click="hogeck('ほげええええええ',$event)">ホゲるボタン</button>
</div>
<!-- HTML -->
<!-- Vue -->
<script>
var app = new Vue({
el: '#hoge',
methods: {
hogeck: function(message1,arg_event){
alert(message1) // ほげええええええ
alert(arg_event.target.textContent) // ホゲるボタン
}
},
})
</script>
<!-- Vue -->
computed
とmethod
の動作の違いを使いこなす
computed
とmethod
の動作が似通っていて、混乱される方がいるかもぢれない(私もそうです)。
大きな違いとしては以下の通り
-
method
- 画面の再描画時に必ず実行される
-
computed
- 呼び出されたプロパティに変化があった場合に実行される(プロパティに変化がない場合は実行されない)
呼び出されたプロパティに変化があった場合
具体的にみてみよう
<!-- HTML -->
<div id="hoge">
<button @click="onclick()">ほげボタン</button> <!-- ほげボタン -->
<div>ホゲった数: {{count}}</div>
<p>hoge_method: {{hoge_method()}}</p>
<p>hoge_computed: {{hoge_computed}}</p>
</div>
</div>
<!-- HTML -->
<!-- Vue -->
<script>
var app = new Vue({
el: '#hoge',
data: {
count: 1,
},
methods: {
onclick: function () {
this.count++;
},
hoge_method: function () {
return Math.random()
}
},
computed: {
hoge_computed: function () {
console.log(this.count)
return Math.random()
}
},
});
</script>
<!-- Vue -->
ご覧のようにホゲった数
が変化する度にhoge_method
とhoge_computed
が実行されていることがわかる。
コード中のこの部分に注目してほしい
computed: {
hoge_computed: function () {
console.log(this.count)
hoge_computed
内でthis.count
を呼び出しており、このthis.count
はボタンを押す度に変化する。
''呼び出されたプロパティ(count)に変化があった''ので、hoge_computed
も実行されたわけだ。
呼び出されたプロパティに変化がない場合
console.log(this.count)
を消して実行してみる
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- HTML -->
<div id="hoge">
<button @click="onclick()">ほげボタン</button> <!-- ほげボタン -->
<div>ホゲった数: {{count}}</div>
<p>hoge_method: {{hoge_method()}}</p>
<p>hoge_computed: {{hoge_computed}}</p>
</div>
</div>
<!-- HTML -->
<!-- Vue -->
<script>
var app = new Vue({
el: '#hoge',
data: {
count: 1,
},
methods: {
onclick: function () {
this.count++;
},
hoge_method: function () {
return Math.random()
}
},
computed: {
hoge_computed: function () {
return Math.random()
}
},
});
</script>
<!-- Vue -->
count
自体はクリックの度に変化しているが、
hoge_computed
ではcount
を呼び出していないので、実行されず、画面上の表示も変わらない。
v-modelを使いこなす
<!-- HTML -->
<div id="hoge">
<input type="text" v-model="hoge" ><br>
<p>{{hoge}}</p>
</div>
</div>
<!-- HTML -->
<!-- Vue -->
<script>
var app = new Vue({
el: '#hoge',
data: {
hoge: "ほげ?"
}
});
</script>
<!-- Vue -->
ご覧のようにフォームの入力に応じて、下の表示(hogeプロパティ)が動的に変化していることがわかる
流れとしては
- フォームの入力値(value)に変化がある度にイベント処理を行って、変化した値をhogeプロパティに反映する ... v-on
- フォームの入力値(value)とhogeプロパティを結びつける ... v-bind
の2ステップとなっている。
上記の流れに倣い、先ほど例示したコードを書き直してみる
<!-- HTML -->
<div id="hoge">
<input type="text" v-bind:value="hoge" v-on:input="hogeck"><br>
<p>{{hoge}}</p>
</div>
</div>
<!-- HTML -->
<!-- Vue -->
<script>
var app = new Vue({
el: '#hoge',
data: {
hoge: "ほげ?"
},
methods: {
hogeck: function (event) {
this.hoge = event.target.value
}
}
});
</script>
<!-- Vue -->
v-modelのv-bindとv-onの対象は入力方式に依存する
v-modelが常にv-bind:value
、v-on:input
から成るわけではない。先ほどのはあくまでも、テキスト入力フォームでの一例にすぎない
例えばこう、
フォーム | v-bind | v-on |
---|---|---|
テキスト、複数行テキスト | value | input |
チェックボックス、ラジオボタン | checked | change |
プルダウンなどの選択リスト | value | change |
templateタグを使いこなす
v-forを使って子要素を複数回表示したい場合、
<div v-for="hoge in hoges" v-bind:key="hoge.id">
<h1>{{hoge.name}}</h1>
</div>
のように親要素内にv-forを入れてやることで出力ができるが、そもそもこのdiv
要素を出力したいないケースがある。
その時は、templateタグを使うと良い
<!-- HTML -->
<div id="hoge">
<template v-for="hoge in hoges">
<h1>{{hoge.name}}</h1>
</template>
</div>
<!-- Vue -->
<script>
var app = new Vue({
el: '#hoge',
data: {
hoges: [{
name: 'ほげ太郎',
id: 1
},
{
name: 'ほげ次郎',
id: 2
},
{
name: 'ほげ三郎',
id: 3
}
]
}
})
</script>

※v-ifにおいても同様にtemplateタグを使うことで要素を出力せずに判定が可能
コンポーネントを使いこなす
コンポーネントとは、再利用可能なVueインスタンス。要素の塊・UIの部品。
'使いまわせるテンプレートのようなもの`と思ってもらえればわかりやすいかも
<!-- HTML -->
<div id="hoge">
<hoge_component></hoge_component> <!-- ほげえええええええ -->
</div>
<!-- Vue -->
<script>
Vue.component(hoge_component', {
template: '<h1>ほげえええええええ</h1>'
})
var app = new Vue({
el: '#hoge'
})
</script>
このとき、<hoge_component>
が<h1>ほげえええええええ</h1>
に置き換わっているのが確認できる。
次にVue.componentの使い方をみてみよう
tag_name
には、要素(テンプレート)を展開したいタグ名を、
html_element
には、展開する予定のHTML要素(テンプレート)を記述する。
Vue.component(tag_name, {template: 'html_element'})
グローバルなコンポーネントを定義する
Vueオブジェクトが指定するel
内であれば、コンポーネントは使い回すことができる。
<!-- HTML -->
<div id="hoge">
<hoge_component> </hoge_component> <!-- ほげえええええええ -->
</div>
<div id="hogehoge"">
<hoge_component> </hoge_component> <!-- ほげえええええええ -->
</div>
<!-- Vue -->
<script>
Vue.component('hoge_component', {
template: '<h1>ほげえええええええ</h1>'
})
var hoge = new Vue({
el: '#hoge'
})
var hogehoge = new Vue({
el: '#hogehoge'
})
</script>
ローカルなコンポーネントを定義する
<!-- HTML -->
<div id="hoge">
<hogecomponent> </hogecomponent> <!-- ほげええええええ!!! -->
</div>
<div id="hogehoge">
<hogecomponent> </hogecomponent>
</div>
<!-- Vue -->
<script>
var local_component = {
template: '<div class="component">ほげええええええ!!!</div>'
};
var hoge = new Vue({
el: '#hoge',
components: {
'hogecomponent': local_component
}
});
var hogehoge = new Vue({
el: '#hogehoge'
});
</script>
この部分でコンポーネントのローカル化を行っている。
components: {
'hogecomponent': local_component
}
使い方はこのような感じ
components: {
'展開するタグ名': `templateを定義した変数・定数`
}
コンポーネントにプロパティを定義する
props
コンポーネントにもprops
でプロパティを定義することができる。
このプロパティは、コンポーネントを呼び出す時に、任意の値を与えることができる。
親から子コンポーネントへ値を渡すときなどに使用される。プロパティというよりも引数
のイメージに近いかも
<!-- HTML -->
<div id="hoge">
<hogecomponent hoge_property='ほげええエェxえぇ'></hogecomponent> <!-- ほげええエェxえぇ -->
</div>
<!-- Vue -->
<script>
Vue.component('hogecomponent', {
props: ['hoge_property'],
template: '<h3>{{ hoge_property }}</h3>'
});
var hoge = new Vue({
el: '#hoge'
});
</script>
propsにvalidationを加える
- propsの方を指定する場合
今回はNumberを型指定したところにあえて、Stringを代入してみる
<!-- HTML -->
<div id="hoge">
<hogecomponent hoge_property='Hogeeeee'></hogecomponent> <!-- ほげええエェxえぇ -->
</div>
<!-- Vue -->
<script>
Vue.component('hogecomponent', {
props: {
hoge_property: {
type: Number,
}
},
template: '<h3>{{ hoge_property }}</h3>'
});
var hoge = new Vue({
el: '#hoge'
});
</script>

実のところ、型を指定したからといって、表示が変わるわけではない。
しかし上記のようなエラーメッセージが出力される。
- requiredを指定した場合
<!-- HTML -->
<div id="hoge">
<hogecomponent></hogecomponent> <!-- ほげええエェxえぇ -->
</div>
<!-- Vue -->
<script>
Vue.component('hogecomponent', {
props: {
hoge_property: {
required: true,
}
},
template: '<h3>{{ hoge_property }}</h3>'
});
var hoge = new Vue({
el: '#hoge'
});
</script>

同様に、あくまでもwarning
は出るが、描写自体への影響はない
- 独自のvalidationを追加した場合
<!-- HTML -->
<div id="hoge">
<hogecomponent hoge_property='hogehoge'></hogecomponent> <!-- ほげええエェxえぇ -->
</div>
<!-- Vue -->
<script>
Vue.component('hogecomponent', {
props: {
hoge_property: {
validator: function(value) {
return value.lrngth < 100;
}
}
},
template: '<h3>{{ hoge_property }}</h3>'
});
var hoge = new Vue({
el: '#hoge'
});
</script>

内部プロパティ
一方でdata
で定義されるのは内部プロパティ。外部から引数を受け付けて、どうこう操作できるものではない。
注意しなければならないのは、内部プロパティを定義する際は必ずfunction()
を使って定義しなければならないこと。
<!-- HTML -->
<div id="hoge">
<hogecomponent></hogecomponent>
</div>
<!-- Vue -->
<script>
Vue.component('hogecomponent', {
data: function () {
return {
count: 0
}
},
template: '<button v-on:click="count++">ほげカウント:{{ count }} times.</button>'
});
new Vue({
el: '#hoge'
});
</script>
slotを使って文字を置き換える
ちょうど<slot> ~ </slot>
で書き込まれた部分がげげげげげげげげ
と置き換わっている。
<!-- HTML -->
<div id="hoge">
<hogecomponent>げげげげげげげげ</hogecomponent> <!-- ほほほほげげげげげげげげほほほほほ -->
</div>
<!-- Vue -->
<script>
Vue.component('hogecomponent', {
template: '<h3>ほほほほ<slot>ほほほ</slot>ほほほほほ</h3>'
});
var hoge = new Vue({
el: '#hoge'
});
</script>