2016-10-07 1 views
0

私はTic-Tac-Toeウェブアプリケーションを作っています。この問題が道路ブロックを投げたので、まだ完成していません。 XまたはOのいずれかが勝利すると、3つの勝ち箱が緑色に変わります(この部分は、後に起こりたいトランジションを削除すると機能します)。ボックスが緑色になると、「ボード」テーブル全体が「バウンス」するはずです。しかし、実際に起こっているのは、 'マーク'(X/O)が表示され、勝利したボックスが緑色に変わる前に 'ボード'がバウンスしているということです。私にとって意味をなさないのは、コード実行の焦点が上から下に向かうべきだが、そのように振舞うようには見えないということです。私はいくつかの異なる方法でコードを再配置しようとしましたが、まだ運がありません。Vue.jsトランジションとエフェクトが順不同で実行

Here is the Codepen

そして、ここのリンクをクリックしたくない人のためのコードです:P(スタイリングのため申し訳ありません、コードスニペットが正しく=/

動作するように望んでいません

ところで、事前に感謝!

console.clear(); 
 
const log = console.log.bind(console); 
 

 
const game = new Vue({ 
 
\t el: '#app', 
 
\t data: { 
 
\t \t turn: 'X', 
 
\t \t over: false, 
 
\t \t board: [[{val:'',bg:''}, {val:'',bg:''}, {val:'',bg:''}], 
 
\t \t \t \t \t [{val:'',bg:''}, {val:'',bg:''}, {val:'',bg:''}], 
 
\t \t \t \t \t [{val:'',bg:''}, {val:'',bg:''}, {val:'',bg:''}]], 
 
\t \t windex: [[[0,0], [0,1], [0,2]], 
 
\t \t \t \t \t \t [[1,0], [1,1], [1,2]], 
 
\t \t \t \t \t \t [[2,0], [2,1], [2,2]], 
 
\t \t \t \t \t \t [[0,0], [1,0], [2,0]], 
 
\t \t \t \t \t \t [[0,1], [1,1], [2,1]], 
 
\t \t \t \t \t \t [[0,2], [1,2], [2,2]], 
 
\t \t \t \t \t \t [[0,0], [1,1], [2,2]], 
 
\t \t \t \t \t \t [[0,2], [1,1], [2,0]]], 
 
\t \t check() { 
 
\t \t \t const arr = this.board.map(x => x.map(y => y.val)); 
 
\t \t \t const winArr = this.windex.map(x => x.map(y => this.board[y[0]][y[1]].val)); 
 
\t \t \t const winner = winArr.map((x,ind) => { 
 
\t \t \t \t if(x.every(y => y == 'X')) return 'X'; 
 
\t \t \t \t if(x.every(y => y == 'O')) return 'O'; 
 
\t \t \t }); 
 
\t \t \t if(winner.includes('X')){ 
 
\t \t \t \t const inds = this.windex[winner.indexOf('X')]; 
 
\t \t \t \t inds.forEach(x => { 
 
\t \t \t \t \t this.board[x[0]][x[1]].bg = 'active'; 
 
\t \t \t \t }); 
 
\t \t \t \t this.over = true; 
 
\t \t \t }; 
 
\t \t \t if(winner.includes('O')){ 
 
\t \t \t \t const inds = this.windex[winner.indexOf('O')]; 
 
\t \t \t \t inds.forEach(x => { 
 
\t \t \t \t \t this.board[x[0]][x[1]].bg = 'active'; 
 
\t \t \t \t }); 
 
\t \t \t \t this.over = true; 
 
\t \t \t }; 
 
\t \t \t if(arr.every(x => x.every(y => y == 'X' || y == 'O'))) 
 
\t \t \t \t this.over = true; 
 
\t \t } 
 
\t }, 
 
\t methods: { 
 
\t \t mark(box) { 
 
\t \t \t if(this.over) return 
 
\t \t \t if(box.val === ''){ 
 
\t \t \t \t box.val = this.turn; 
 
\t \t \t \t this.turn = this.turn == 'X' ? 'O' : 'X'; 
 
\t \t \t } else 
 
\t \t \t \t \t alert('Invalid turn') 
 
\t \t \t \t this.check() 
 
\t \t } 
 
\t } 
 
});
@import 'https://fonts.googleapis.com/css?family=Oswald'; 
 

 
h1 { 
 
\t font-family: 'Oswald'; 
 
\t letter-spacing: 1.5vw; 
 
\t text-align: center; 
 
\t margin:1vw; 
 
} 
 

 
table { 
 
\t margin-left: auto; 
 
\t margin-right: auto; 
 
\t border-collapse: separate; 
 
\t border-spacing: 2px; 
 
} 
 

 
.square { 
 
\t width: 100px; 
 
\t height: 100px; 
 
\t background-color: #6C7A89; 
 
\t text-align: center; 
 
\t color: white; 
 
\t cursor: pointer; 
 
\t text-align: center; 
 
\t line-height: 100px; 
 
\t font-size: 50px; 
 
\t font-family: 'Oswald'; 
 
\t display: block; 
 
} 
 

 
.square:hover { 
 
\t opacity: .8; 
 
} 
 

 
td { 
 
\t vertical-align: middle; 
 
} 
 

 
.active { 
 
\t background-color: #00B16A; 
 
} 
 

 
.bounce-leave-active { 
 
    animation: bounce-out 1.5s; 
 
} 
 

 
@keyframes bounce-out { 
 
    0% { 
 
    transform: scale(1); 
 
    } 
 
    50% { 
 
    transform: scale(1.5); 
 
    } 
 
    100% { 
 
    transform: scale(0); 
 
    } 
 
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.1/vue.min.js"></script> 
 

 
<div id='app'> 
 
\t <h1>TIC-TAC-TOE</h1> 
 
\t <transition name='bounce'> 
 
\t <table v-if='!over'> 
 
\t \t <tr v-for='row in board'> 
 
\t \t \t <td v-for='box in row'> 
 
\t \t \t \t <div class='square' 
 
\t \t \t \t \t \t v-bind:class='{active:box.bg}' 
 
\t \t \t \t \t \t v-on:click='mark(box)'> 
 
\t \t \t \t \t {{box.val}} 
 
\t \t \t \t </div> 
 
\t \t \t </td> 
 
\t \t </tr> 
 
\t </table> 
 
\t </transition> 
 
</div>

+0

'setTimeout'に' this.over = true'を入れれば、それはあなたが望むように動作します。すなわち、 'setTimeout(()=> this.over = true、0);' –

+0

ありがとう素晴らしい仕事をした。それがなくてもうまくいかなかった理由は何ですか?私はどこにでも見ましたが、私はGoogleに何が本当によくわからないのです。 – Dirtier

+0

ブラウザが再ペイントするときには、それが関係している可能性があります –

答えて

0

コードはブロックとして実行されます。 UIはあなたの設定activeoverの間で再描画されないので、UIに関しては効果的に同時に発生します。 overv-ifバインディングをトリガーします。そのため、コンテンツは再描画されず、トランジションされます。

VueはnextTickを提供しています。 setTimeout(..., 0)のように、ブロックからコマンドを取り出しますが、実行する前にDOMアップデートサイクルが発生していることを確認します。

+0

ああ、ありがとう、たくさんの男。私はそれがブロックとして実行されていたことを認識していませんでした。私はVueのドキュメントでnextTickについて読んだことがありましたが、ここでそれが当てはまるかどうかはわかりませんでした。私は、それが更新された後にイベントをトリガーするためのものだと思っていました。 – Dirtier

関連する問題