Tic Tac Toe Teil 0: Vergleich von Svelte und React
Tic Tac Toe Teil 1: Svelte und Canvas 2D
Tic Tac Toe Teil 2: Staatenloses Rückgängigmachen / Wiederherstellen
Tic Tac Toe, Teil 3: Rückgängig / Wiederherstellen mit Befehlsspeicher
Tic Tac Toe Teil 4: Interaktion mit dem Flask Backend über HTTP
Auf der React-Website gibt es ein Tutorial , das die Entwicklung des Tic Tac Toe-Spiels beschreibt. Ich habe beschlossen, die Entwicklung dieses Spiels auf Svelte zu wiederholen. Der Artikel behandelt nur die erste Hälfte des Tutorials vor der Implementierung der Bewegungsgeschichte. Für die Einarbeitung in das Framework ist dies völlig ausreichend. Jeder Abschnitt des Artikels entspricht dem Abschnitt des Tutorials und enthält Links zum Quellcode beider Frameworks.
Reagiere - Svelte
App.svelte<script> import Board from './Board.svelte'; </script> <div class="game"> <div class="game-board"> <Board /> </div> <div class="game-info"> <div></div> <ol></ol> </div> </div> <style> .game { font: 14px "Century Gothic", Futura, sans-serif; margin: 20px; display: flex; flex-direction: row; } .game-info { margin-left: 20px; } ol { padding-left: 30px; } </style>
Board.svelte <script> import Square from './Square.svelte'; </script> <div class="status">Next player: X</div> <div class="board"> {#each Array(9) as square} <Square /> {/each} </div> <style> .board { width: 102px; } .status { margin-bottom: 10px; } </style>
Square.svelte <button></button> <style> button { background: #fff; border: 1px solid #999; float: left; font-size: 24px; font-weight: bold; line-height: 34px; height: 34px; margin-right: -1px; margin-top: -1px; margin-bottom: -1px; padding: 0; text-align: center; width: 34px; } button:focus { outline: none; } </style>
Jede Komponente wird in einer separaten Datei ausgeführt. Eine Komponente kann Code-, HTML-Markup- und CSS-Stile enthalten. Die Verwendung verschachtelter Komponenten wird gezeigt: Die Square-Komponente wird in die Board-Komponente importiert, die Board-Komponente wird in die App-Komponente importiert. Dargestellt wird jeder Block in der Board-Komponente verwendet. Stile ändern sich selten, deshalb habe ich sie nach dem HTML-Markup platziert, um sie nicht noch einmal umzudrehen.
Reagiere - Svelte
Square deklariert eine Werteigenschaft.
<script> export let value = ''; </script> <button>{value}</button>
Board zeigt die Verwendung von Array-Indizes zum Auffüllen von Zellen.
<div class="board"> {#each Array(9) as square, i} <Square value={i}/> {/each} </div>
Reagiere - Svelte
Durch Klicken in die Zelle wird ein Kreuz angezeigt. Square hat den DOM- HandleClick- Ereignishandler für Mausklicks hinzugefügt. Statusvariable hinzugefügt, um ein Kreuz in einer Zelle anzuzeigen.
<script> export let value = ''; let state = ''; function handleClick() { state = 'X'; } </script> <button on:click={handleClick}> {state} </button>
Reagiere - Svelte
Bis zu diesem Moment wurde der Zustand der Zellen in ihnen gespeichert. Nachdem die Speicherung des Spielstatus auf die Board-Komponente übertragen wurde, wird der Status aller Zellen in einem Array gespeichert. Der Handle-Handler clickClick wurde ebenfalls in die Board-Komponente verschoben. Square zeigt jetzt den Zellenstatus mithilfe der value-Eigenschaft erneut an.
Board.svelte <script> import Square from './Square.svelte'; let state = { squares: Array(9).fill(''), }; function handleClick(i) { const squares = state.squares.slice(); squares[i] = 'X'; state.squares = squares; } </script> <div class="status">Next player: X</div> <div class="board"> {#each state.squares as value, i} <Square {value} on:click={e => handleClick(i)}/> {/each} </div>
Square.svelte <script> export let value = ''; </script> <button on:click> {value} </button>
Reagiere - Svelte
Das Aussehen eines Zehs nach dem Kreuz wurde hinzugefügt.
Board.svelte <script> import Square from './Square.svelte'; let state = { squares: Array(9).fill(''), xIsNext: true, }; function handleClick(i) { const squares = state.squares.slice(); squares[i] = state.xIsNext ? 'X' : 'O'; state.squares = squares; state.xIsNext = !state.xIsNext; } </script> <div class="status">Next player: {state.xIsNext ? 'X' : 'O'}</div> <div class="board"> {#each state.squares as value, i} <Square {value} on:click={e => handleClick(i)}/> {/each} </div>
Reagiere - Svelte
Funktion hinzugefügt, um den Gewinner zu bestimmen. Berechnen Sie den Gewinner in einer separaten Datei helper.js. Es ist verboten, nach dem Sieg auf bereits eingerichtete Zellen zu klicken.
heplers.js export function calculateWinner(squares) { const lines = [ [0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6], ]; for (let i = 0; i < lines.length; i++) { const [a, b, c] = lines[i]; if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) { return squares[a]; } } return null; }
Board.svelte <script> import Square from './Square.svelte'; import { calculateWinner } from './helpers.js'; let state = { squares: Array(9).fill(''), xIsNext: true, }; $: winner = calculateWinner(state.squares); function handleClick(i) { if (winner || state.squares[i]) return; const squares = state.squares.slice(); squares[i] = state.xIsNext ? 'X' : 'O'; state.squares = squares; state.xIsNext = !state.xIsNext; } </script> <div class="status"> {#if winner} <b>Winner: {winner}</b> {:else} Next player: {state.xIsNext ? 'X' : 'O'} {/if} </div> <div class="board"> {#each state.squares as value, i} <Square {value} on:click={e => handleClick(i)} /> {/each} </div>
Ich habe nicht mehr vor, das Tutorial durchzugehen, ich habe mich mit dem Framework vertraut gemacht.
GitHub-Repository
https://github.com/nomhoi/tic-tac-toe
Installieren des Spiels auf dem lokalen Computer:
git clone git@github.com:nomhoi/tic-tac-toe.git cd tic-tac-toe npm install npm run dev
Wir starten das Spiel in einem Browser unter der Adresse: http: // localhost: 5000 / .
UPDATE: Artikel und Quellcode gemäß Kommentaren in Kommentaren korrigiert.
UPDATE2: Tutorial-Repository auf GitHub hinzugefügt.