vue.jsはじめました@超基礎編
最近業務でvueを触る機会が多いので備忘録として残します。
ここで記述しているvueのバージョンは2.5.16
です。
v-onについて
v-on
ディレクティブはイベントリスナに加え、Vueインスタンスのメソッドを呼び出すことができます。
<button v-on:click="doSomething">Click</button> <!--省略記法--> <button @click="doSomething">Click</button>
v-on
は省略できるのでコードを書く際には@イベントリスナ名
としましょう。
慣れるまではv-on
を書くことをすすめます。
v-modelについて
フォームの入力値をvue側のデータとバインドする「双方向データバインディング」を簡単に実現することができます。これがVue.jsの主要な機能とも言えます。
<div id="app"> <input v-model="messgae"> <p>{{messgae}}</p> </div>
new Vue({ el: "#app", data: { messgae: "Hello" } })
上記のコードを載せたので試してみてください。
inputタグの値が変更される度にバインドしたmessage
が変更されていると思います。
v-model
がしていることは二つあります。
- inputタグにvue側のデータをバインドする
- イベントハンドリングをしてデータを更新している
1について下記のようにまずはHTML側とvueをバインドします。
<input v-bind:value="message">
2では下記のように値を更新しています。
まずinput
イベントハンドラでユーザーが入力した値を取得します。
<input @input="message">
その後、vue側のデータ変数に実際にユーザーが入力した値を代入します。
this.message = e.target.value
v-on
の仕組みは大事なのでここで何をしているかは言語化できるようにしましょう。
v-bindディレクティブについて
bindとは他動詞では〜を結びつける
という意味です。
Vue側のデータをDOMと結びつけることを意味します。
リアクティブにデータを更新したいときに使用します。
最も簡単な例はテキストとしてバインドする例です。
<div id="app"> {{ message }} </div>
new Vue({ el: "#app", data: { message: "Hello Vue" } })
二重のブランケットの場合はプレーンなテキストとして表示されます。 htmlタグとして認識させたい場合は、v-htmlというディレクティブを使用します。
<div id="app"> <p v-html="message"></p> </div>
new Vue({ el: "#app", data: { message: "<h1 style='color:red;'>Hello, Vue!!!</h1>" } })
vueのバージョン1では、下記にように三重のブランケットにしてhtmlとして認識させるようにしていたみたいです。
<div id="app"> {{{ message }}} </div>
またHTML属性にバインドするケースも多いです。 例えばapiから受け取ったデータをテキストリンクとして表示させたいとき。
<a v-bind:href="itemLink">Google</a>
new Vue({ el: '#app', data: { itemLink: "http://google.com" } })
また省略記法としてv-bind
の代わりに:属性名
と書くことが多いので慣れておきましょう。
イベント修飾子
イベント修飾子は、クリックやキー操作などDOMイベントの変更をしたいときに使用します。
今回はその中でも.stop
修飾子について説明したいと思います。
例えばモーダルがあるとします。
- モーダルのコンテンツを覆っているDOM →
modal
- モーダルのコンテンツのDOM →
modal_content
<div class="modal"> <div class="modal_content"></div> </div>
モーダルのコンテンツに何か入力フォームやクリックするものなどあったときに、同じイベントをハンドルした要素がネストしている場合、イベントの発生元であるe.target.value
から親要素へ向かって設定している要素のイベントが連鎖して行われます。
そのようなときにmodal
にはクリックするとモーダルが非表示になるイベント、modal_content
にも入力フォームなどに入力するようなイベントを設定していると入力しようとしたときにモーダルが非表示になってしまいモーダルが閉じてしまいます。
このようなケースの場合など.stop
修飾子を使用します。
まずは.stop
修飾子をつけないで試してみます。
<div id="app"> <div class="modal" @click="getClassinfo('modal')"> modal <div class="modal_content" @click.stop="getClassinfo('modal_content')"> modal_content </div> </div> </div>
new Vue({ el: '#app', methods: { getClassinfo: function(className) { console.log(className) } } })
modal_contentをくりっくした出力結果が以下になります。
modal_content modal
modal_contentがクリックされるたびにmodalのクリックイベントも発火しています。
今度は.stop
修飾子をつけて、modal_contentをクリックしてみてください。
<div id="app"> <div class="modal" @click="getClassinfo('modal')"> modal <div class="modal_content" @click.stop="getClassinfo('modal_content')"> modal_content </div> </div> </div>
javascriptのコードは変わらないので省略します。
出力結果は以下のようになります。
modal_content
.stop
をつけることでイベントの伝搬を止めたい箇所を指定できました。
親→子へ値を渡す方法
<div id="app"> <child-component number="3"></child-component> </div>
Vue.component('child-component', { template: `<div>{{number}}</div>`, props: ['number'] }) new Vue({ el: '#app', })
ここでは子コンポーネントである'child-component
にpropsの値として1を渡しています。=
の右辺の値が親が渡したい値であり左辺のnumber
は子の方でpropsとして定義する必要があります。
子→親へ何かをするとき
子のコンポーネントの状態に応じて親コンポーネントに何かしてほしいとき、また子が持っているデータを親に渡したいときは$emit
を使用します。
<div id="app"> <div class="parents"> <child-component @child-event="getData"></child-component> </div> </div>
Vue.component('child-component', { template: `<div @click='giveData'>クリック</div>`, methods: { giveData(){ this.$emit("child-event") } } }) new Vue({ el: '#app', methods: { getData(){ console.log("受け取りました") } } })
ここで大切になるのがカスタムイベントです。
$emit
を使って任意のタイミング(ここではクリックをしたとき)でカスタムイベントであるchild-event
を発火させます。それを親側で受け取るためには親側でv-on
を使って子のカスタムイベントをハンドリングします。
そしてchild-event
が発火したタイミング(クリックしたとき)で親で定義したgetData
が実行され下記のような出力結果になります。
受け取りました
上記では子のコンポーネントのイベントに応じて親のメソッドを実行してるだけでした。 では、子のコンポーネントから何かしらのデータを送ってみましょう。 htmlファイルは変更箇所がないので記述しません。
Vue.component('child-component', { template: `<div @click='giveData'>クリック</div>`, methods: { giveData(){ this.$emit("child-event", "come from child-component") } } }) new Vue({ el: '#app', methods: { getData(message){ console.log(message) } } })
出力結果です。
come from child-component
$emit
の第一引数にカスタムイベント名、第二引数に渡したいデータを追加してあげると子→親
にデータを与えることができます。
今は決め打ちで値を渡してみましたが、子のコンポーネントで定義したdata属性のpersons
という中身がオブジェクトの集まりのデータを渡してみます。
Vue.component('child-component', { template: `<div @click='giveData'>クリック</div>`, data: function() { return { persons: [ {name: "田中", age: 23}, {name: "佐藤", age: 22}, {name: "武田", age: 17} ] } }, methods: { giveData(){ this.$emit("child-event", this.persons) } } }) new Vue({ el: '#app', methods: { getData(persons){ console.log(persons) } } })
クリックするとconsole.log上にこのように子から親にデータが渡ってきていることがわかると思います。
(3) [{…}, {…}, {…}, __ob__: Observer]
上記のコードはこちらに書いたので試してみてください。
今度はvue-class-components
について記事を書きたいと思います。