vue实现棋子移动
实现棋子移动的基本思路
在Vue中实现棋子移动通常涉及以下几个核心概念:数据驱动、事件监听和动态样式绑定。通过维护棋子的位置状态,结合用户交互(如点击或拖拽),更新数据并触发视图重新渲染。
定义棋子数据模型
使用Vue的data或ref(Composition API)定义棋子的初始位置和状态。例如:
// Options API
data() {
return {
pieces: [
{ id: 1, x: 0, y: 0, type: 'pawn' },
{ id: 2, x: 1, y: 1, type: 'rook' }
],
selectedPiece: null
}
}
// Composition API
const pieces = ref([
{ id: 1, x: 0, y: 0, type: 'pawn' },
{ id: 2, x: 1, y: 1, type: 'rook' }
]);
const selectedPiece = ref(null);
渲染棋子到棋盘
通过v-for动态渲染棋子,并使用内联样式或CSS类绑定位置:
<div class="chess-board">
<div
v-for="piece in pieces"
:key="piece.id"
class="chess-piece"
:class="[piece.type, { selected: selectedPiece === piece.id }]"
:style="{ left: `${piece.x * 50}px`, top: `${piece.y * 50}px` }"
@click="selectPiece(piece.id)"
></div>
</div>
处理棋子选中逻辑
在方法中实现选中逻辑,高亮当前棋子并存储选中状态:
methods: {
selectPiece(id) {
this.selectedPiece = id;
}
}
// Composition API
function selectPiece(id) {
selectedPiece.value = id;
}
实现移动逻辑
监听棋盘点击事件,将选中的棋子移动到目标位置。需检查目标位置是否合法(如是否被其他棋子占据):
methods: {
movePiece(targetX, targetY) {
if (this.selectedPiece === null) return;
const piece = this.pieces.find(p => p.id === this.selectedPiece);
if (isValidMove(piece, targetX, targetY)) {
piece.x = targetX;
piece.y = targetY;
}
this.selectedPiece = null;
}
}
拖拽移动的高级实现
若需支持拖拽,可使用原生拖拽API或第三方库(如vuedraggable):
<div
v-for="piece in pieces"
:key="piece.id"
draggable="true"
@dragstart="dragStart(piece.id)"
@dragend="dragEnd"
@dragover.prevent
@drop="drop($event, piece)"
></div>
methods: {
dragStart(id) {
this.draggedPiece = id;
},
drop(event, targetPiece) {
if (this.draggedPiece) {
const piece = this.pieces.find(p => p.id === this.draggedPiece);
piece.x = targetPiece.x;
piece.y = targetPiece.y;
}
}
}
动画过渡效果
使用Vue的<transition>或CSS动画增强移动体验:
<transition name="slide">
<div v-if="show" class="chess-piece"></div>
</transition>
.slide-enter-active {
transition: all 0.5s ease;
}
.slide-leave-active {
transition: all 0.8s cubic-bezier(1.0, 0.5, 0.8, 1.0);
}
完整示例代码
组合上述逻辑的简单实现:
<template>
<div class="board" @click.self="deselect">
<div
v-for="piece in pieces"
:key="piece.id"
class="piece"
:style="{ left: `${piece.x * 50}px`, top: `${piece.y * 50}px` }"
:class="{ selected: selectedPiece === piece.id }"
@click="selectPiece(piece.id)"
></div>
</div>
</template>
<script>
export default {
data() {
return {
pieces: [
{ id: 1, x: 2, y: 3 },
{ id: 2, x: 5, y: 1 }
],
selectedPiece: null
};
},
methods: {
selectPiece(id) {
this.selectedPiece = id;
},
deselect() {
this.selectedPiece = null;
}
}
};
</script>
<style>
.board {
position: relative;
width: 400px;
height: 400px;
background-color: #f0d9b5;
}
.piece {
position: absolute;
width: 40px;
height: 40px;
background-color: #b58863;
border-radius: 50%;
cursor: move;
}
.piece.selected {
box-shadow: 0 0 10px yellow;
}
</style>






