0

我正在制作一个井字游戏网络应用程序。它还没有完成,因为这个问题已经引发了障碍。当 X 或 O 获胜时,它应该将 3 个获胜框变为绿色(如果我删除我想要在此之后发生的转换,这部分会起作用)。一旦盒子变成绿色,整个“Board”桌子应该“弹开”。但实际发生的情况是,在“标记”(X/O)出现之前,“棋盘”就弹了出来,获胜的盒子变成了绿色。对我来说没有意义的是代码执行的重点应该是从上到下,但它的行为似乎不是那样的。我尝试了几种不同的方式重新排列代码,但仍然没有运气。

这是代码笔

这里是那些不想点击链接的人的代码:P(对不起样式,代码片段不想正常工作=/

顺便说一句,提前谢谢!

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

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

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

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

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

.square:hover {
	opacity: .8;
}

td {
	vertical-align: middle;
}

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

4

1 回答 1

0

您的代码作为一个块运行;UI 不会在您的设置active和之间重新绘制over,因此就 UI 而言,它们同时有效地发生。over触发绑定,因此v-if内容不会被重新绘制,它们只是过渡出来。

VuenextTick允许您对事物进行排序。就像setTimeout(..., 0),它把你的命令带出块,但它确保在执行之前已经发生了一个 DOM 更新周期。

于 2016-10-07T13:15:12.403 回答