使用keypress()来控制所有Vue交互

时间:2017-06-29 17:29:57

标签: javascript oop vue.js

我正在将游戏从Javascript / jQuery重写为Vue。游戏不使用鼠标,一切都由键盘控制。

玩家使用“向上”和“向下”箭头循环按钮,选择“回车”键,然后返回“返回”箭头。

每次玩家选择一个选项时,数据都存储在“游戏”数组中,以便在玩游戏时,它可以显示正确的游戏和玩家。

所以我的问题是,在Vue中构建它的标准方法是什么?

我已经读过,如果你使用jQuery在Vue项目中进行DOM操作,你做错了什么,但我不知道是否有任何其他方法可以让keypress()在所有页面中以其工作方式工作jQuery的。

这是当前构建页面的方式(使用Javascript / jQuery):

{{1}}

2 个答案:

答案 0 :(得分:1)

以下是您的请求的完整示例。它太大了,无法解释所有内容,因此如果您需要澄清,请提出问题。

这里我基本上在window对象上设置一个事件监听器,并用Vue逻辑处理它。



new Vue({
  el: '#app',
  data: {
    buttons: [
      {
        'choosegame': 'Choose a game',
        'highscores': 'Highscores',
        'settings': 'Settings'
      },
      {
        'Checkers': { game: 'checkers', players: '2', playersmax: '2' },
        'Bingo': { game: 'bingo', playersmin: '2', playersmax: '4' },
        'Scrabble': { game: 'scrabble', players: '2', playersmax: '2' }
      },
      {
        'Jimmy': 'Jimmy',
        'Billy': 'Billy',
        'Arnold': 'Arnold'
      },
    ],
    page: 0, // currentPage
    selectedButton: 'choosegame',
    game: null, // chosen game and player
    player: null
  },
  methods: {
    handleKeyPress: function (e) {
      const keyCode = String(e.keyCode || e.code || e.keyIdentifier);
      if (keyCode === '13') { // enter
        if (this.page < 3) {
          if (this.page === 1) this.game = this.selectedButton;
          if (this.page === 2) this.player = this.selectedButton;
          if (this.page === 0 && this.selectedButton !== 'choosegame') {
            console.log('not implemented yet. choose a game instead');
          } else {
            this.page++;
            this.selectedButton = Object.keys(this.currentButtons)[0];
          }
        }
      } else if (keyCode === '38' || keyCode === '40') { // navigate up or down
        const buttons = this.buttons[this.page];
        const pageKeys = Object.keys(buttons);
        const currIndex = pageKeys.findIndex(key => this.selectedButton === key);
        const newIndex = (keyCode == 38) // up
          ? (currIndex === 0)
            ? pageKeys.length - 1
            : currIndex - 1
          : (keyCode == 40) // down
            ? (currIndex === (pageKeys.length - 1))
              ? 0
              : currIndex + 1
            : currIndex;
        this.selectedButton = pageKeys[newIndex]
      }
    }
  },
  computed: {
    currentButtons: function () {
      return this.buttons[this.page] || [] // current buttons object 
    }
  },
  mounted: function () {
    // add an event listener for keypress
    window.addEventListener('keypress', this.handleKeyPress)
  }
});
&#13;
.button_selected {
  background-color: red;
}
&#13;
<script src="https://unpkg.com/vue/dist/vue.js"></script>

<div id="app">
  <div v-if="page == 0">
    <div class="button"
      v-for="(button, index) in currentButtons" 
      :key="index" 
      :class="{'button_selected': index === selectedButton}">{{ button }}
    </div>
  </div>
  <div v-if="page == 1 || page == 2">
    <div class="button"
      v-for="(button, index) in currentButtons" 
      :key="index" 
      :class="{'button_selected': index === selectedButton}">{{ index }}
    </div>
  </div>
  <div v-if="page == 3">
    You made it here! {{ player }} gonna play {{ game }}
  </div>
</div>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

可以在任何具有焦点的DOM元素上使用键事件。通常,这是输入字段,但是如果你启用了对div的焦点(通过将其tabindex属性设置为-1)并实际上将焦点设置在它上(或者焦点位于其内部的元素不会停止事件冒泡),它将处理键盘事件。

这里有一种方法:我制作一个keyBus;主应用程序根据按下的键将事件发送到总线。组件(菜单,游戏,等等)将公共汽车作为道具并响应事件。

不幸的是,对于片段,关键事件触发滚动,我认为这是无法捕获的。你想要隐藏所有的溢出。

new Vue({
  el: '#app',
  data: {
    keyBus: new Vue()
  },
  methods: {
    handleEnter() {
      this.keyBus.$emit('enter');
    },
    handleUp() {
      this.keyBus.$emit('up');
    },
    handleDown() {
      this.keyBus.$emit('down');
    }
  },
  components: {
    menuComponent: {
      template: '#menu-template',
      props: ['keyBus'],
      data() {
        return {
          ups: 0,
          downs: 0,
          enters: 0
        }
      },
      mounted() {
        this.keyBus.$on('up', () => ++this.ups);
        this.keyBus.$on('down', () => ++this.downs);
        this.keyBus.$on('enter', () => ++this.enters);
      }
    }
  },
  mounted() {
    this.$el.focus();
  }
});
#app {
  height: 300px;
  width: 300px;
  background-color: #eee;
}
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.min.js"></script>
<div id="app" tabindex="-1" @keyup.enter="handleEnter" @keyup.up="handleUp" @keyup.down="handleDown">
  <menu-component :key-bus="keyBus">
  </menu-component>
</div>

<template id="menu-template">
<div>
Ups: {{ups}} <br>
Downs: {{downs}} <br>
Enters: {{enters}} <br>
</div>
</template>