Vue.jsを利用した地図アプリ(後編)
親子コンポーネントのイベント処理
地図アプリに配置した上下左右のボタンのイベント処理を実装します. このアプリは3つのコンポーネントで構成されています. 親コンポーネントは main.vue ,子コンポーネントは vmap.vue と vcontroller.vue です. 親子コンポーネント間でメソッドを呼び出したり,データを受け渡すには幾つか方法がありますが, 子から親 ,親から子 ではその方法が異なります. 今回の地図アプリでは下記の流れでイベント処理を行います.
- vcontroller.vue(子) のボタンをクリックすると,main.vue(親) の
move
メソッドを呼び出す(子から親). - main.vue(親) の
move
メソッドが呼び出されると,vmap.vue(子) のmove
メソッドを呼び出す(親から子).
子から親のメソッドを実行
子コンポーネントから親コンポーネントのメソッドを呼び出すには$emitを利用します.
main.vue(親)
親コンポーネントで move
メソッドを定義します.
このmove
メソッドはアラートを表示するだけです.
このメソッドを v-on
ディレクティブを利用して,vcontorller
タグの属性として指定します.
このとき,move-event
という属性名になっていることに注意してください.
<template>
<div>
<h1>Vue.jsで地図アプリ</h1>
<vmap></vmap>
<vcontroller v-on:move-event="move"></vcontroller>
</div>
</template>
<script>
import vmap from "./vmap"
import vcontroller from "./vcontroller"
export default{
components:{
vmap,
vcontroller
},
methods:{
move(direction){
// アラートを表示
alert(direction);
}
}
}
</script>
vcontroller.vue(子)
子コンポーネントでも move
メソッドを定義しています.
このmove
メソッドは,$emit
を利用してmove-event
として登録されている親コンポーネントの move
メソッドを呼び出します.
また,move
メソッドは,v-on
ディレクティブを利用して,ボタンのクリックがトリガーとなっています.
このとき,メソッドの引数としてleft, up, right, downのいずれかの文字列が渡されることに注意してください.
<template>
<div>
<div id="mycontroller">
<div id="mypad">
<v-fa class="pad" v-on:click="move('left')" icon="long-arrow-alt-left" />
<v-fa class="pad" v-on:click="move('up')" icon="long-arrow-alt-up" />
<v-fa class="pad" v-on:click="move('right')" icon="long-arrow-alt-right" />
<v-fa class="pad" v-on:click="move('down')" icon="long-arrow-alt-down" />
</div>
</div>
</div>
</template>
<script>
// ・・・省略・・・
export default{
name: "vcontroller",
methods:{
move(direction){
// 親コンポーネントであるmain.vueのmoveメソッドを呼び出す
this.$emit("move-event", direction)
}
}
}
</script>
ボタンをクリックすると,対応した文字列がアラートに表示されます.
親から子のメソッドを実行
親コンポーネントから子コンポーネントのメソッドを呼び出すには$refsを利用します.
vmap.vue(子)
子コンポーネントで move
メソッドを定義します.
このメソッドでは,引数の文字列に応じて,Leefletの地図オブジェクトの中心を東西南北の方向に少しだけ移動させます.
<script>
import L from 'leaflet'
import "leaflet/dist/leaflet.css";
export default{
name: "vmap",
mounted: function(){
// ・・・省略・・・
},
data: function(){
// ・・・省略・・・
},
methods:{
move(direction){
this.offset = 0.005
switch(direction){
case "left":
this.latlng = [this.latlng[0], this.latlng[1] - this.offset]
this.map.panTo(this.latlng)
break;
case "up":
this.latlng = [this.latlng[0] + this.offset, this.latlng[1]]
this.map.panTo(this.latlng)
break;
case "right":
this.latlng = [this.latlng[0], this.latlng[1] + this.offset]
this.map.panTo(this.latlng)
break;
case "down":
this.latlng = [this.latlng[0] - this.offset, this.latlng[1]]
this.map.panTo(this.latlng)
break;
}
}
}
}
</script>
main.vue(親)
親コンポーネントでは,子コンポーネントのvmap
タグにrefs
属性を指定します.
refs
属性を指定することで,子コンポーネントのDOM要素を直接操作することができます.
move
メソッドでは,this.$refs.cmap
で子コンポーネントを参照し,
子コンポーネントの move
メソッドを呼び出しています.
<template>
<div>
<h1>Vue.jsで地図アプリ</h1>
<vmap ref="cmap"></vmap>
<vcontroller v-on:move-event="move"></vcontroller>
</div>
</template>
<script>
import vmap from "./vmap"
import vcontroller from "./vcontroller"
export default{
components:{
vmap,
vcontroller
},
methods:{
move(direction){
// 子コンポーネントであるvmap.vueのmoveメソッドを呼び出す
this.$refs.cmap.move(direction);
}
}
}
</script>
下記のようにボタンをクリックすると,地図が東西南北に移動すれば完成です.