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

标签 javascript oop vue.js

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

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

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

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

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

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

// this is the first page the player sees
<div class="page1">
    <div class="button button_selected" data-link="choosegame">Choose a game</div>
    <div class="button" data-link="highscores">Highscores</div>
    <div class="button" data-link="settings">Settings</div>
</div>

// if the player selects "choose a game", it shows this page:
<div class="choosegame">
    <div class="button" data-link="chooseplayers" data-options="{game:'checkers',players:'2',playersmax:'2'}">Checkers</div>
    <div class="button" data-link="chooseplayers" data-options="{game:'bingo',playersmin:'2',playersmax:'4'}">Bingo</div>
    <div class="button" data-link="chooseplayers" data-options="{game:'scrabble',players:'2',playersmax:'2'}">Scrabble</div>
</div>

// if the player selects a game (ex. checkers), it shows this page:
<div class="chooseplayers">
    <div class="button" data-link="playgame" data-options="{player:'Jimmy'}">Jimmy</div>
    <div class="button" data-link="playgame" data-options="{player:'Billy'}">Billy</div>
    <div class="button" data-link="playgame" data-options="{player:'Arnold'}">Arnold</div>
</div>

// after players are selected, it shows this page:
<div class="playgame">
    PLAYING!
</div>

最佳答案

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

这里我基本上在 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)
  }
});
.button_selected {
  background-color: red;
}
<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>

关于javascript - 使用 keypress() 控制所有 Vue 交互,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44831541/

相关文章:

javascript - 在 Jasmine 测试中监视 Angular element.css 函数

java - 构造函数采用两个整数,它们不能相等,实现这个的最佳方法是什么?

typescript - 是否可以为多类型参数类/函数的多个参数创建类型别名?

vue.js - Axios - 如何在我的 Get() 请求中对注入(inject)的值进行编码?

javascript - 如何在 vanilla Javascript 中创建、添加自定义属性和触发自定义事件

javascript - 带 Promise 的 Redux-thunk 不起作用

javascript - Firebase 消息传递和身份验证相结合来设置自定义 token

java - 有没有更好的方法来通过对对象数组执行碰撞检测?

php - 了解 PHP 中的魔法方法

vue.js - 在vue中添加键盘事件监听器