Svelte — это способ создания пользовательских интерфейсов следующего поколения.
В то время как фреймворки, такие как React, Vue и Angular, выполняют основную часть своей работы в браузере, Svelte поднимает ее на следующий уровень. Он выполняет свою работу при сборке приложения и компилирует приложение Svelte в эффективный ванильный JavaScript. Таким образом, вы получаете лучшее из обоих миров. Вы пишете свой код на Svelte, который облегчает чтение, повторное использование и все другие преимущества, которые вы получаете, когда используете фреймворк, и делает его невероятно быстрым веб-приложением, которое соответствует ванильному JavaScript, так что вам не нужно нет накладных расходов на JavaScript каркас, который вы используете.
Svelte позволяет писать меньше кода. Он также не использует концепцию Virtual DOM, популяризованную React. Вместо этого он хирургически обновляет DOM при изменении состояния приложения, поэтому приложение запускается быстро и остается быстрым.
Предпосылки
Для этого урока вам необходимы базовые знания HTML, CSS и JavaScript.
Вы также должны установить последнюю версию Node.js.
Мы также будем использовать npx
, который устанавливается по умолчанию вместе с Node.js.
В этом уроке мы будем использовать yarn
. Если у вас еще не установлена yarn
, установите ее отсюда .
Чтобы убедиться, что мы находимся на одной странице, вот версии, используемые в этом руководстве:
- Узел 12.10.0
- NPX 6.11.3
- пряжа 1.17.3
Начало работы с Svelte
В этом уроке мы будем создавать игру Tic Tac Toe в Svelte. К концу вы сможете быстро приступить к работе с Svelte и начать создавать свои собственные приложения на Svelte.
Для начала мы должны подготовить наше приложение с помощью degit . degit
более или менее degit
на git clone
, но гораздо быстрее. Вы можете узнать больше об этом здесь .
Сделайте новый проект, набрав в терминале следующее:
$ npx degit sveltejs/template tic-tac-toe-svelte
npx
позволяет использовать команду degit
не устанавливая ее глобально.
До npx
нам пришлось бы выполнить два следующих шага, чтобы достичь того же результата:
$ npm install --global degit $ degit sveltejs/template tic-tac-toe-svelte
Благодаря npx
мы не раздуваем наше глобальное пространство имен и всегда используем последнюю версию degit
.
degit
клонирует репозиторий https://github.com/sveltejs/template в папку tic-tac-toe-svelte
.
Перейдите в каталог tic-tac-toe-svelte
и установите зависимости, набрав в терминале следующее:
$ cd tic-tac-toe-svelte $ yarn
Теперь запустите приложение, набрав в терминале следующее:
$ yarn dev
Теперь откройте браузер и перейдите по адресу http: // localhost: 5000, и вы должны увидеть следующее:
Если вы App.svelte
папку src/
, вы увидите два файла: App.svelte
и main.js
main.js
— это точка входа в приложение Svelte.
Откройте main.js
и вы должны увидеть следующее:
import App from './App.svelte'; const app = new App({ target: document.body, props: { name: 'world' } }); export default app;
Приведенный выше файл импортирует App.svelte
и создает его экземпляр, используя target
элемент. Он помещает компонент в DOM document.body
. Он также передает реквизиты имени компоненту App
. Эта опора будет доступна в App.svelte
.
Компоненты в Svelte написаны с использованием файлов .svelte
которые содержат HTML, CSS и JavaScript. Это будет выглядеть знакомо, если вы работали с Vue .
Теперь откройте App.svelte
и вы должны увидеть следующее:
<script> export let name; </script> <style> h1 { color: purple; } </style> <h1>Hello {name}!</h1>
Во-первых, у нас есть тег script
, в котором мы имеем именованный экспорт с именем name
. Это должно быть похоже на опору, упомянутую в main.js
Затем у нас есть тег style
который позволяет нам стилизовать все элементы в этом конкретном файле, который ограничен только этим файлом, поэтому нет проблем каскадирования.
Затем внизу у нас есть тег h1
, внутри которого мы имеем Hello {name}!
, name
в фигурных скобках будет заменено фактическим значением. Это называется интерполяцией значений. Вот почему Hello world!
печатается на экране.
Базовая структура компонента Svelte
Все файлы .svelte
основном имеют следующую структуру:
<script> /* Javascript logic */ </script> <style> /* CSS styles */ </style> <!-- HTML markup -->
HTML-разметка будет иметь некоторый дополнительный специфичный для Svelte синтаксис, а остальное — просто обычный HTML, CSS и JavaScript.
Делаем крестики-нолики в Svelte
Давайте начнем с создания нашей игры Tic Tac Toe.
Замените main.js
следующим:
import App from './App.svelte' const app = new App({ target: document.body, }) export default app
Мы в основном удалили свойство props
из экземпляра компонента App
.
Теперь замените App.svelte
следующим:
<script> const title = "Tic Tac Toe"; </script> <svelte:head> <title>{title}</title> </svelte:head> <h1>{title}</h1>
Здесь мы инициализируем постоянную переменную title
строкой Tic Tac Toe
.
Затем в разметке ниже мы используем специальный синтаксис Svelte, svelte:head
, для установки свойства title
в теге head
.
Это в основном похоже на это:
<head> <title>Tic Tac Toe</title> </head>
Но преимущество использования синтаксиса svelte:head
заключается в том, что title
можно изменить во время выполнения.
Затем мы используем то же свойство title
в нашем теге h1
. Теперь это должно выглядеть так:
Теперь создайте два других файла в каталоге src/
именами Board.svelte
и Square.svelte
.
Откройте Square.svelte
и вставьте следующее:
<script> export let value; </script> <style> .square { flex: 1 0 25%; width: 50px; height: 70px; background-color: whitesmoke; border: 2px solid black; margin: 5px; padding: 5px; font-size: 20px; text-align: center; } .square:hover { border: 2px solid red; } </style> <button class="square">{value}</button>
По сути, мы создаем кнопку и стилизуем ее.
Теперь откройте Board.svelte
и вставьте следующее:
<script> import Square from "./Square.svelte"; let squares = [null, null, null, null, null, null, null, null, null]; </script> <style> .board { display: flex; flex-wrap: wrap; width: 300px; } </style> <div class="board"> {#each squares as square, i} <Square value={i} /> {/each} </div>
Здесь мы импортировали компонент Square
. Мы также инициализировали массив squares
, который будет содержать наши данные X
и 0
, которые в настоящее время null
.
Каждая петля в Svelte
В разметке HTML мы использовали специальный синтаксис Svelte для циклов. Это похоже на цикл Array.forEach
в Array.forEach
JavaScript. Синтаксис выглядит так:
{#each squares as square, i} <Square value={i} /> {/each}
Это squares.length
более девяти раз, так как squares.length
равен 9
. Значение square
в первой итерации равно null
, поскольку первый элемент равен null
а значение i
равно 0
поскольку индекс равен 0
в первый раз. Значение square
остается null
на каждой итерации, поскольку все значения массива squares
в настоящее время равны null
, но значение i
продолжает увеличиваться от 0
до 8
как это значение индекса.
Затем он передает значение i
как value
prop компоненту Square
.
Теперь это должно выглядеть так:
Теперь, когда у нас есть квадраты, давайте добавим немного логики.
Во-первых, нам нужно отобразить следующий ход, будь то его X
или 0
. Кроме того, давайте удостоверимся, что квадраты можно щелкнуть с помощью X
и 0
.
Для этого добавьте следующий код в Board.svelte
:
<script> . . . let xIsNext = true; $: status = "Next Player: " + (xIsNext ? "X" : "0"); function handleClick(i) { if (!squares[i]) { squares[i] = xIsNext ? "X" : "0"; xIsNext = !xIsNext; } } </script> <style> h3 { color: red; } . . . </style> <h3>{status}</h3> <div class="board"> {#each squares as square, i} <Square value={square} handleClick={() => handleClick(i)} /> {/each} </div>
Приведенный выше код инициализирует переменную xIsNext
как логическое значение. Это логическое значение будет продолжать переключаться относительно следующего хода.
Если X
— следующий ход, тогда xIsNext
будет true
. Если 0
— следующий ход, то xIsNext
будет false
. По умолчанию установлено значение true
.
Тогда у нас есть переменная status
. Это особый тип переменной, известный как реактивное присваивание. Если поставить знак доллара ($) перед ним, он станет реагировать на изменения. Поэтому, если xIsNext
снова изменится, то status
будет обновлен до его нового значения. Когда xIsNext
равен true
, status
будет Next Player: X
, а когда xIsNext
равен false
, status
будет Next Player: 0
.
Затем мы передаем value
prop как square
. Это будет отображать X
или 0
зависимости от содержимого.
Затем у нас есть функция handleClick
которая вызывается при нажатии на квадрат. Функция handleClick
должна быть передана компоненту Square
как опора, где она реализована для прослушивания щелчка. Таким образом, без изменения Square.svelte
, клик по квадрату не будет работать.
В любом случае, функция handleClick
получает индекс i
так как мы должны хранить содержимое доски в нашем square
массиве для сравнения, если кто-то выиграл или проиграл, или чтобы проверить, является ли это ничьей.
Первая строка, которая является условием if
, требуется, чтобы убедиться, что мы не изменим содержимое квадрата, если оно уже заполнено. Если он уже null
, только тогда он войдет в тело условия if
.
Во второй строке проверяется значение xIsNext
и если оно true
, тогда X
ставится в качестве значения квадрата, а если оно false
, в качестве значения квадрата ставится 0
.
Наконец, xIsNext
переключается для воспроизведения следующего хода.
Теперь отредактируйте Square.svelte
следующим образом:
<script> . . . export let handleClick; </script> <style> . . . </style> <button class="square" on:click={handleClick}>{value || ""}</button>
Единственное, что мы здесь добавили, это именованный экспорт handleClick
и обработчик on on:click
для button
, которая указывает на handleClick
. Это передано от Board.svelte
. Без приведенного выше кода, щелчок не будет работать. Кроме того, мы отображаем содержимое внутри кнопки только в том случае, если оно не равно null
то есть мы отображаем только при наличии X
и 0
.
Теперь это выглядит так:
Если вы попытаетесь щелкнуть внутри квадратов, то X
и 0
будут отображаться соответствующим образом. Вы также можете увидеть изменение статуса следующим образом:
В поисках победителя
Теперь, когда мы можем играть в игру, давайте выясним, как найти победителя, проигравшего или проверить, является ли это ничьей.
Откройте Board.svelte
и добавьте следующее:
<script> let winner = null; . . . function handleClick(i) { if (!squares[i]) { squares[i] = xIsNext ? "X" : "0"; xIsNext = !xIsNext; winner = calculateWinner(squares); } } function calculateWinner(squares) { const winningCombo = [ [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 < winningCombo.length; i++) { const [a, b, c] = winningCombo[i]; if (squares[a] && squares[a] === squares[b] && squares[a] === squares
)
return `Winner: $ {squares [a]}`;
}const isDraw = squares.every (square => square! == null);
вернуть isDraw? «Это ничья»: ноль;
}
</ Скрипт>,
,
,{# если победитель}
<H3> {победитель} </ h3>
{:} Еще
<H3> {состояния} </ h3>
{/если}<div class = "board">
,
,
,
</ DIV>
В приведенном выше коде мы инициализируем переменную winner
которая отслеживает победителя. Изначально это null
. Затем, после каждого клика, мы вызываем handleClick
как вы можете видеть в функции handleClick
и устанавливаете его возвращаемое значение в winner
.
calculateWinner
- это функция, которая принимает массив squares
и определяет победителя. winningCombo
- это массив, который определяет выигрышную комбинацию. Чтобы выиграть матчи X
и 0
, вам нужно либо иметь прямую линию по вертикали и горизонтали, либо диагональную линию. Приведенный выше массив является возможным списком выигрышных комбинаций.
В цикле for
мы проверяем, находятся ли значения в массиве squares
по прямой (горизонтальной или вертикальной) или диагональной линии, сравнивая индексы. Если они есть, то мы объявляем победителя. Если это не так, мы проверяем, заполнены ли все значения, и если это правда, то это ничья, так как у нас больше нет мест, чтобы играть в X
и 0
. В противном случае мы возвращаем null
если игра все еще включена.
Наконец, мы добавляем специфичный для Svelte синтаксис для if...else
. Если winner
не равен null
, отобразить winner
, иначе отобразить status
.
Если кто-то выигрывает, теперь это должно выглядеть так:
И если это ничья, теперь она должна выглядеть так:
Теперь давайте добавим способ перезапустить игру.
В том же файле Board.svelte
добавьте следующее:
<script> . . . function restartGame() { squares = [null, null, null, null, null, null, null, null, null]; xIsNext = true; winner = null; } . . . </script> . . . {#if winner} <button on:click={restartGame}>Restart Game</button> {/if}
Приведенный выше код добавит в приложение кнопку « Restart Game
, которая restartGame
функцию restartGame
которая сбрасывает все необходимые значения для нового запуска.
Поэтому, если вы выиграете игру или получите ничью, вы должны увидеть следующий экран с кнопкой « Restart Game
:
Весь файл Board.svelte
теперь должен выглядеть так:
<script> import Square from "./Square.svelte"; let winner = null; let squares = [null, null, null, null, null, null, null, null, null]; let xIsNext = true; $: status = "Next Player: " + (xIsNext ? "X" : "0"); function restartGame() { squares = [null, null, null, null, null, null, null, null, null]; xIsNext = true; winner = null; } function handleClick(i) { if (!squares[i]) { squares[i] = xIsNext ? "X" : "0"; xIsNext = !xIsNext; winner = calculateWinner(squares); } } function calculateWinner(squares) { const winningCombo = [ [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 < winningCombo.length; i++) { const [a, b, c] = winningCombo[i]; if (squares[a] && squares[a] === squares[b] && squares[a] === squares
)
return `Winner: $ {squares [a]}`;
}const isDraw = squares.every (square => square! == null);
вернуть isDraw? «Это ничья»: ноль;
}
</ Скрипт><Стиль>
h3 {
красный цвет;
}.board {
дисплей: гибкий;
flex-wrap: обертывание;
ширина: 300 пикселей;
}
</ Стиль>{# если победитель}
<H3> {победитель} </ h3>
{:} Еще
<H3> {состояния} </ h3>
{/если}<div class = "board">
{# Каждый квадрат как квадрат, я}
<Square value = {square} handleClick = {() => handleClick (i)} />
{/} Каждого
</ DIV>{# если победитель}
<button on: click = {restartGame}> Перезапустить игру </ button>
{/если}
Теперь вы можете создать производственный код, набрав в терминале следующее:
$ yarn build
Это public/bundle.js
файл public/bundle.js
который содержит оптимизированный код, готовый к работе.
Весь код можно найти на Github .
Вы можете найти демо приложения здесь .
Вывод
В этом уроке мы создали полную игру с использованием Svelte. Мы многому научились, создав нашу игру Tic Tac Toe.
Svelte - это радикально новый компилятор, который можно использовать для создания быстродействующих веб-приложений. Он сильно отличается от традиционных фреймворков в том смысле, что он преобразует все в простой JavaScript, что делает его очень быстрым.
Если вы использовали фреймворки, такие как React или Vue, то подобрать Svelte будет очень просто. Дайте ему шанс, и вы не будете разочарованы.
Конечно, это была лишь верхушка айсберга. Посетите официальный веб-сайт для более удивительного контента и удивительного раздела примеров , который содержит массу примеров с REPL.