我正在将游戏从Javascript / jQuery重写为Vue。游戏不使用鼠标,一切都由键盘控制。
玩家使用“向上”和“向下”箭头循环按钮,选择“回车”键,然后返回“返回”箭头。
每次玩家选择一个选项时,数据都存储在“游戏”数组中,以便在玩游戏时,它可以显示正确的游戏和玩家。
所以我的问题是,在Vue中构建它的标准方法是什么?
我已经读过,如果你使用jQuery在Vue项目中进行DOM操作,你做错了什么,但我不知道是否有任何其他方法可以让keypress()在所有页面中以其工作方式工作jQuery的。
这是当前构建页面的方式(使用Javascript / jQuery):
{{1}}
答案 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;
答案 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>