2016-10-07 6 views
0

Я делаю веб-приложение Tic-Tac-Toe. Это еще не закончено, так как эта проблема подняла дорожный блок. Когда выигрывает X или O, он должен превратить три выигрышные коробки в зеленый цвет (эта часть работает, если я удалю переход, который я хочу после этого). Когда поля зеленые, таблица «Board» должна «отскакивать». Но на самом деле происходит то, что «Совет» подпрыгивает до того, как «метка» (X/O) даже отображается, а выигрышные коробки становятся зелеными. Что для меня не имеет смысла, так это то, что фокус выполнения кода должен быть сверху вниз, но, похоже, он не ведет себя так. Я попытался переставить код несколькими разными способами и до сих пор не повезло.Vue.js Переходы и эффекты, выполняемые не по заказу

Here is the Codepen

А вот код для тех, кто не хочет, чтобы нажать на ссылку: P (Sorry для стайлинга, фрагмент кода не хочет работать правильно =/

BTW, спасибо заранее!

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

Если вы положили 'this.over = true' в' setTimeout', он работает так, как вы хотите ... т.е. 'setTimeout (() => this.over = true, 0);' –

+0

Большое спасибо, что отлично работал. Любая конкретная причина, почему он не работал без него? Я повсюду смотрел, но я даже не уверен, что делать с Google. – Dirtier

+0

Возможно, это связано с тем, когда браузер перекрашивает –

ответ

0

Ваш код работает как блок; пользовательский интерфейс не перерисовывает между вашими настройками active и over, поэтому они происходят эффективно в то же время, что и в пользовательском интерфейсе. over запускает привязку v-if, поэтому содержимое не перерисовывается, они просто переходят.

Vue предоставляет nextTick, чтобы вы могли упорядочить вещи. Например, setTimeout(..., 0), он выводит вашу команду из блока, но гарантирует, что перед выполнением произойдет цикл обновления DOM.

+0

О, хорошо, большое спасибо. Я не понимал, что он работает как блок. Я читал о nextTick в документах Vue, но не знал, что это применимо здесь. Я думал, что это просто для запуска событий после того, как все обновлено. – Dirtier

 Смежные вопросы

  • Нет связанных вопросов^_^