connexo
connexo

Reputation: 56773

How to bind custom event handler from vue-touch-events to a custom component in Vue.js

I'm currently implementing a classical Minesweeper game in Vue.js which is working fine so far https://github.com/franktopel/defuse, Demo http://connexo.de/defuse/.

Screenshot of Defuse Game

Now I would like to add touch support because as of now, to mark a field as "contains a mine" it is required that you right-click the field. Right-clicking is obviously not available on touch devices, so I would like to add longtap support. I'm using native events click and click.right from the parent component for each field, so the field does not handle the events, but the parent component that instantiates these fields does.

I've found this https://github.com/jerrybendy/vue-touch-events and added it to my project, yet it seems I cannot use this on the component tag (see https://github.com/franktopel/defuse/blob/master/src/components/Defuse.vue):

    <m-field
      v-for="field in row"
      :field="field"
      :key="`${field.x},${field.y}`"
      @click.native="open(field)"
      @click.right.native.prevent="toggleBombMarker(field)"
      v-touch:longtap="toggleBombMarker(field)"
    ></m-field>

because that marks all fields without any user interaction and the console keeps producing

You may have an infinite update loop in a component render function.

This is how my field objects (which I'm passing to the field component) are created:

let Field = function (x, y) {
  this.x = x
  this.y = y
  this.isOpen = false
  this.hasBomb = false
  this.isMarked = false
  this.numNeighbourBombs = null
}

module.exports = Field

I have also tried emitting a custom event from inside my field component, yet I don't know how I can pass the triggering field to the event handler from there.

Can anyone push me in the right direction?

Upvotes: 2

Views: 2507

Answers (1)

Decade Moon
Decade Moon

Reputation: 34306

According to the vue-touch-events docs, the v-touch directive doesn't work in the same way as v-on; v-touch must be given a function to execute, whereas the toggleBombMarker(field) expression probably returns undefined.

If you want to pass extra parameters to the v-touch handler, your handler must return a function like this:

methods: {
  toggleBombMarker(field) {
    return () => {
      // your handler code here
    }
  }
}

Upvotes: 2

Related Questions