元Webデザイナー兼コーダーの備忘録

HTML,CSSの入門記事やブログのカスタマイズについてアウトプットしています。

 メニュー

【Vue.js】コンポーネントのイベント:$emit(),$event

私自身、Vue.jsの理解がまだまだ浅いです。メモ程度のものとして見て頂ければと思います。

今回は、コンポーネントにイベントを設定する方法について書きます。ポイントは、$emit()と$eventです。イベントをどのように紐づけるのかや、イベントでの値の渡し方について注目すると良いかもしれません。

コンポーネントのイベント:$emit()

ex.)ボタンクリックでフォントサイズの値を更新する例を見ます。以下は、画面イメージです。

ボタンをクリックすると下図のようになります。

コードは以下です。

<div id="app">
  <div :style="{ fontSize: postFontSize + 'em' }">
    <blog-post
      v-for="post in posts"
      v-bind:key="post.id"
      v-bind:post="post"
      v-on:enlarge-text="postFontSize += 0.1"
    ></blog-post>
  </div>
</div>
Vue.component('blog-post', {
  props: ['post'],
  template: `
    <div>
      <h3>{{ post.title }}</h3>
      <button v-on:click="$emit('enlarge-text')">テキストを拡大する</button>
      <div v-html="post.content"></div>
    </div>
  `
})

var app = new Vue({
  el: '#app',
  data: {
    posts: [
      { id: 1, title: 'HTML入門', content: 'HTML入門!' },
      { id: 2, title: 'CSS入門', content: 'CSS入門!' },
      { id: 3, title: 'JavaScript入門', content: 'JavaScript入門!' }
    ],
    postFontSize: 1
  }
})

データプロパティにpostFontSizeを追加します。この値を増加させます。<button v-on:click="$emit('イベント名')">...</button>でイベントを送ります。v-on:enlarge-text="postFontSize += 0.1"でイベントを受け取り、postFontSizeの値を更新します。

イベントと値を送る:$event

イベントを値付きで送るには、$emit()の2番目のパラメータに値を指定します。受け取るときは、$eventでアクセスします。

<div id="app">
  <div :style="{ fontSize: postFontSize + 'em' }">
    <blog-post
      v-for="post in posts"
      v-bind:key="post.id"
      v-bind:post="post"
      v-on:enlarge-text="postFontSize += $event"
    ></blog-post>
  </div>
</div>
Vue.component('blog-post', {
  props: ['post'],
  template: `
    <div>
      <h3>{{ post.title }}</h3>
      <button v-on:click="$emit('enlarge-text', 0.1)">テキストを拡大する</button>
      <div v-html="post.content"></div>
    </div>
  `
})

var app = new Vue({ ... })

イベントハンドラがメソッドの場合

Vueインスタンスのmethodsに、イベントが発生したときのメソッドを定義します。イベントの値は、そのメソッドの1番目のパラメータに渡されます。

<div id="app">
  <div :style="{ fontSize: postFontSize + 'em' }">
    <blog-post
      v-for="post in posts"
      v-bind:key="post.id"
      v-bind:post="post"
      v-on:enlarge-text="onEnlargeText"
    ></blog-post>
  </div>
</div>
Vue.component('blog-post', {
  props: ['post'],
  template: `
    <div>
      <h3>{{ post.title }}</h3>
      <button v-on:click="$emit('enlarge-text', 0.1)">テキストを拡大する</button>
      <div v-html="post.content"></div>
    </div>
  `
})

var app = new Vue({
  el: '#app',
  data: {
    posts: [
      { id: 1, title: 'HTML入門', content: 'HTML入門!' },
      { id: 2, title: 'CSS入門', content: 'CSS入門!' },
      { id: 3, title: 'JavaScript入門', content: 'JavaScript入門!' }
    ],
    postFontSize: 1
  },
  methods: {
    onEnlargeText: function(enlargeAmount){
      this.postFontSize += enlargeAmount
    }
  }
})

参考サイト