2017-06-29 10 views
0

Javascript/jQueryからVueにゲームを書き換えています。ゲームはマウスを使用せず、すべてがキーボードによって制御されます。keypress()を使用してすべてのVueインタラクションを制御

プレイヤーは、「上へ」および「下へ」の矢印を使用して、ボタンを押し、「Enter」キーを押して選択し、「戻る」矢印を押して戻ります。

プレーヤーがオプションを選択するたびに、データがゲームの配列に格納され、ゲームがプレイされるときに正しいゲームとプレーヤーが表示されます。

私の質問は、Vueでこれを構築する標準的な方法は何でしょうか?

私は、VueプロジェクトでDOM操作を行うためにjQueryを使用している場合、何か間違っていることを読んでいますが、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> 
+0

スタート:[修飾キー](https://vuejs.org/v2/guide/events.html#Key-Modifiers) –

+0

のみの入力フィールドで動作します。 – supercoolville

+0

イベントハンドラをドキュメントに停止させたいですか? – Bert

答えて

1

はあなたの要求のための完全な例です。すべてを説明するには大きすぎますので、明確にする必要がある場合は質問してください。

ここでは、基本的にウィンドウオブジェクトにイベントリスナーを設定し、それを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>

+1

' this.handleKeyPress、bind(this) 'は必要ありません。メソッドはインスタンス化中にVueにバインドされます。 – Bert

+0

完了!!!!!!!!!!!!!!私が変更しなければならなかったのは、何らかの理由でアップキーとダウンキーがうまく動作しなかったので、 "キー押し"を "キーダウン"に変更することだけでした。本当にありがとう!!!!!!!!!!!!!!!!!!! – supercoolville

+0

@BertEvansあなたが正しいです、それは拘束なしで動作します。 – wostex

0

キーイベントを中心とした任意のDOM要素に使用することができます。通常は入力フィールドですが、divのフォーカスを有効にして(tabindex属性を-1に設定して)、フォーカスを実際に設定している(またはフォーカスがイベントのバブリングを停止しない要素内にある)キーボードイベントを処理します。

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>

関連する問題