Vue.js公式サンプルのグリッドコンポーネントで、行にマウスオーバーイベントを設定する

投稿者: Anonymous

Vue.jsでマウスオーバーイベントをハンドリングする方法について質問です。

やりたいこと
グリッドコンポーネントのサンプルプログラムで、
行にマウスオーバーすると行の色が変化する。
https://jp.vuejs.org/examples/grid-component.html

やったこと

_x000D_

_x000D_

// register the grid component_x000D_
Vue.component('demo-grid', {_x000D_
  template: '#grid-template',_x000D_
  props: {_x000D_
    data: Array,_x000D_
    columns: Array,_x000D_
    filterKey: String_x000D_
  },_x000D_
  data: function() {_x000D_
    var sortOrders = {}_x000D_
    this.columns.forEach(function(key) {_x000D_
      sortOrders[key] = 1_x000D_
    })_x000D_
    return {_x000D_
      sortKey: '',_x000D_
      sortOrders: sortOrders_x000D_
    }_x000D_
  },_x000D_
  methods: {_x000D_
    sortBy: function(key) {_x000D_
      this.sortKey = key_x000D_
      this.sortOrders[key] = this.sortOrders[key] * -1_x000D_
    },_x000D_
    mouseover: function(event) {_x000D_
      alert(event.target);_x000D_
      alert(event.target.textContent);_x000D_
    }_x000D_
  }_x000D_
})_x000D_
_x000D_
// bootstrap the demo_x000D_
var demo = new Vue({_x000D_
  el: '#demo',_x000D_
  data: {_x000D_
    searchQuery: '',_x000D_
    gridColumns: ['name', 'power'],_x000D_
    gridData: [{_x000D_
      name: 'Chuck Norris',_x000D_
      power: Infinity_x000D_
    }, {_x000D_
      name: 'Bruce Lee',_x000D_
      power: 9000_x000D_
    }, {_x000D_
      name: 'Jackie Chan',_x000D_
      power: 7000_x000D_
    }, {_x000D_
      name: 'Jet Li',_x000D_
      power: 8000_x000D_
    }]_x000D_
  }_x000D_
})

_x000D_

body {_x000D_
  font-family: Helvetica Neue, Arial, sans-serif;_x000D_
  font-size: 14px;_x000D_
  color: #444;_x000D_
}_x000D_
_x000D_
table {_x000D_
  border: 2px solid #42b983;_x000D_
  border-radius: 3px;_x000D_
  background-color: #fff;_x000D_
}_x000D_
_x000D_
th {_x000D_
  background-color: #42b983;_x000D_
  color: rgba(255, 255, 255, 0.66);_x000D_
  cursor: pointer;_x000D_
  -webkit-user-select: none;_x000D_
  -moz-user-select: none;_x000D_
  -user-select: none;_x000D_
}_x000D_
_x000D_
td {_x000D_
  background-color: #f9f9f9;_x000D_
}_x000D_
_x000D_
th,_x000D_
td {_x000D_
  min-width: 120px;_x000D_
  padding: 10px 20px;_x000D_
}_x000D_
_x000D_
th.active {_x000D_
  color: #fff;_x000D_
}_x000D_
_x000D_
th.active .arrow {_x000D_
  opacity: 1;_x000D_
}_x000D_
_x000D_
.arrow {_x000D_
  display: inline-block;_x000D_
  vertical-align: middle;_x000D_
  width: 0;_x000D_
  height: 0;_x000D_
  margin-left: 5px;_x000D_
  opacity: 0.66;_x000D_
}_x000D_
_x000D_
.arrow.asc {_x000D_
  border-left: 4px solid transparent;_x000D_
  border-right: 4px solid transparent;_x000D_
  border-bottom: 4px solid #fff;_x000D_
}_x000D_
_x000D_
.arrow.dsc {_x000D_
  border-left: 4px solid transparent;_x000D_
  border-right: 4px solid transparent;_x000D_
  border-top: 4px solid #fff;_x000D_
}_x000D_
_x000D_
#search {_x000D_
  margin-bottom: 10px;_x000D_
}

_x000D_

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.24/vue.js"></script>_x000D_
<!-- component template -->_x000D_
<script type="text/x-template" id="grid-template">_x000D_
  <table>_x000D_
    <thead>_x000D_
      <tr>_x000D_
        <th v-for="key in columns" @click="sortBy(key)" :class="{active: sortKey == key}">_x000D_
          {{key | capitalize}}_x000D_
          <span class="arrow" :class="sortOrders[key] > 0 ? 'asc' : 'dsc'">_x000D_
          </span>_x000D_
        </th>_x000D_
      </tr>_x000D_
    </thead>_x000D_
    <tbody>_x000D_
      <tr v-for="_x000D_
        entry in data_x000D_
        | filterBy filterKey_x000D_
        | orderBy sortKey sortOrders[sortKey]" @mouseover="mouseover">_x000D_
        <td v-for="key in columns">_x000D_
          {{entry[key]}}_x000D_
        </td>_x000D_
      </tr>_x000D_
    </tbody>_x000D_
  </table>_x000D_
</script>_x000D_
_x000D_
<!-- demo root element -->_x000D_
<div id="demo">_x000D_
  <form id="search">_x000D_
    Search_x000D_
    <input name="query" v-model="searchQuery">_x000D_
  </form>_x000D_
  <demo-grid :data="gridData" :columns="gridColumns" :filter-key="searchQuery">_x000D_
  </demo-grid>_x000D_
</div>

_x000D_

_x000D_

_x000D_

html側のtr要素に@mouseoverイベントを追加しましたが、
javascript側でevent.targetのプロパティを見てもtdが返ってきます。
当然tdのスタイルを変更してもマスの色しか変わりません。
行全体の色を変更するにはどうしたらいいでしょうか?

HTML側

   <tr v-for="
    entry in data
    | filterBy filterKey
    | orderBy sortKey sortOrders[sortKey]" @mouseover="mouseover">

js側

mouseover: function(event) {
  alert(event.target);
  alert(event.target.textContent);
}

よろしくお願いします。

解決

event.currentTarget を使って下さい。

簡単に言うと、
イベントが発生した要素(event.target)と、
イベントをキャッチした要素(event.currentTarget)の
2種類ある、ということです。

イベントバブリングについてお調べになると、理解が深まると思います。
DOMイベントのキャプチャ/バブリングを整理する 〜 JSおくのほそ道 #017 – Qiita

なお、やりたいことが、行全体の色を変えるだけでしたら、私なら css を書くと思います。

tr:hover td {
  background-color: red
}

_x000D_

_x000D_

// register the grid component_x000D_
Vue.component('demo-grid', {_x000D_
  template: '#grid-template',_x000D_
  props: {_x000D_
    data: Array,_x000D_
    columns: Array,_x000D_
    filterKey: String_x000D_
  },_x000D_
  data: function() {_x000D_
    var sortOrders = {}_x000D_
    this.columns.forEach(function(key) {_x000D_
      sortOrders[key] = 1_x000D_
    })_x000D_
    return {_x000D_
      sortKey: '',_x000D_
      sortOrders: sortOrders_x000D_
    }_x000D_
  },_x000D_
  methods: {_x000D_
    sortBy: function(key) {_x000D_
      this.sortKey = key_x000D_
      this.sortOrders[key] = this.sortOrders[key] * -1_x000D_
    },_x000D_
    mouseover: function(event) {_x000D_
      //alert(event.target);_x000D_
      //alert(event.target.textContent);_x000D_
    }_x000D_
  }_x000D_
})_x000D_
_x000D_
// bootstrap the demo_x000D_
var demo = new Vue({_x000D_
  el: '#demo',_x000D_
  data: {_x000D_
    searchQuery: '',_x000D_
    gridColumns: ['name', 'power'],_x000D_
    gridData: [{_x000D_
      name: 'Chuck Norris',_x000D_
      power: Infinity_x000D_
    }, {_x000D_
      name: 'Bruce Lee',_x000D_
      power: 9000_x000D_
    }, {_x000D_
      name: 'Jackie Chan',_x000D_
      power: 7000_x000D_
    }, {_x000D_
      name: 'Jet Li',_x000D_
      power: 8000_x000D_
    }]_x000D_
  }_x000D_
})

_x000D_

body {_x000D_
  font-family: Helvetica Neue, Arial, sans-serif;_x000D_
  font-size: 14px;_x000D_
  color: #444;_x000D_
}_x000D_
_x000D_
table {_x000D_
  border: 2px solid #42b983;_x000D_
  border-radius: 3px;_x000D_
  background-color: #fff;_x000D_
}_x000D_
_x000D_
th {_x000D_
  background-color: #42b983;_x000D_
  color: rgba(255, 255, 255, 0.66);_x000D_
  cursor: pointer;_x000D_
  -webkit-user-select: none;_x000D_
  -moz-user-select: none;_x000D_
  -user-select: none;_x000D_
}_x000D_
_x000D_
td {_x000D_
  background-color: #f9f9f9;_x000D_
}_x000D_
_x000D_
tr:hover td {_x000D_
  background-color: red_x000D_
}_x000D_
_x000D_
th,_x000D_
td {_x000D_
  min-width: 120px;_x000D_
  padding: 10px 20px;_x000D_
}_x000D_
_x000D_
th.active {_x000D_
  color: #fff;_x000D_
}_x000D_
_x000D_
th.active .arrow {_x000D_
  opacity: 1;_x000D_
}_x000D_
_x000D_
.arrow {_x000D_
  display: inline-block;_x000D_
  vertical-align: middle;_x000D_
  width: 0;_x000D_
  height: 0;_x000D_
  margin-left: 5px;_x000D_
  opacity: 0.66;_x000D_
}_x000D_
_x000D_
.arrow.asc {_x000D_
  border-left: 4px solid transparent;_x000D_
  border-right: 4px solid transparent;_x000D_
  border-bottom: 4px solid #fff;_x000D_
}_x000D_
_x000D_
.arrow.dsc {_x000D_
  border-left: 4px solid transparent;_x000D_
  border-right: 4px solid transparent;_x000D_
  border-top: 4px solid #fff;_x000D_
}_x000D_
_x000D_
#search {_x000D_
  margin-bottom: 10px;_x000D_
}

_x000D_

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.24/vue.js"></script>_x000D_
<!-- component template -->_x000D_
<script type="text/x-template" id="grid-template">_x000D_
  <table>_x000D_
    <thead>_x000D_
      <tr>_x000D_
        <th v-for="key in columns" @click="sortBy(key)" :class="{active: sortKey == key}">_x000D_
          {{key | capitalize}}_x000D_
          <span class="arrow" :class="sortOrders[key] > 0 ? 'asc' : 'dsc'">_x000D_
          </span>_x000D_
        </th>_x000D_
      </tr>_x000D_
    </thead>_x000D_
    <tbody>_x000D_
      <tr v-for="_x000D_
        entry in data_x000D_
        | filterBy filterKey_x000D_
        | orderBy sortKey sortOrders[sortKey]" @mouseover="mouseover">_x000D_
        <td v-for="key in columns">_x000D_
          {{entry[key]}}_x000D_
        </td>_x000D_
      </tr>_x000D_
    </tbody>_x000D_
  </table>_x000D_
</script>_x000D_
_x000D_
<!-- demo root element -->_x000D_
<div id="demo">_x000D_
  <form id="search">_x000D_
    Search_x000D_
    <input name="query" v-model="searchQuery">_x000D_
  </form>_x000D_
  <demo-grid :data="gridData" :columns="gridColumns" :filter-key="searchQuery">_x000D_
  </demo-grid>_x000D_
</div>

_x000D_

_x000D_

_x000D_

回答者: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *