React, Vue и Angular почти занимают большую часть веб-разработки, но за последние полгодаSvelteПостепенно привлекайте все больше и больше внимания людей. Что такого особенного в этом фреймворке Svelte? В этой статье будут проанализированы причины популярности Svelte и использование Svelte для создания простого приложения для книжного магазина (книжный магазин), которое поможет вам быстро начать работу с этой структурой.
Почему Svelte популярен?
Чтобы понять, почему Svelte популярен, мы должны сначала рассмотреть проблемы таких фреймворков, как React и Vue.
большое время работы - большое время работы
React и Vue — это среды выполнения. Так называемый фреймворк, основанный на времени выполнения, означает, что код самого фреймворка также будет упакован в финальный bundle.js и отправлен в браузер пользователя. Когда пользователь выполняет различные операции на вашей странице для изменения состояния компонента, среда выполнения фреймворка будет вычислять (diff), какие узлы DOM необходимо обновить в соответствии с новым состоянием (состоянием) компонента, тем самым обновляя представление. Итак, насколько велики эти коды времени выполнения, вы можете увидеть некоторые сообществаСтатистические данные:
Name | Size |
---|---|
Ember 2.2.0 | 435K |
Ember 1.13.8 | 486K |
Angular 2 | 566K |
Angular 2 + Rx | 766K |
Angular 1.4.5 | 143K |
Vue 2.4.2 | 58.8K |
Inferno 1.2.2 | 48K |
Preact 7.2.0 | 16K |
React 0.14.5 + React DOM | 133K |
React 0.14.5 + React DOM + Redux | 139K |
React 16.2.0 + React DOM | 97.5K |
Из приведенной выше таблицы видно, что среди наиболее часто используемых фреймворков самый маленький Vue имеет 58 КБ, а React — 97,5 КБ. Другими словами, если вы используете React в качестве среды разработки, даже если ваш бизнес-код очень прост, размер вашего первого набора экранов должен начинаться со 100 тыс. Конечно 100к это не так уж и много, но вещи относительные.По сравнению с большими системами управления 100к это точно не много, но для тех приложений которые чувствительны к времени загрузки первого экрана (таких как Taobao, домашняя страница Jingdong), размер пакета 100 тыс. В некоторых случаях, когда сетевая среда не очень хороша или мобильный терминал действительно влияет на работу пользователя. Так как же уменьшить размер исполняемого кода фреймворка? Самый эффективный способ уменьшить объем исполняемого кода — вообще не использовать среду выполнения. На самом деле, оглядываясь назад на историю веб-разработки, когда мы использовали Jquery и Bootstrap давным-давно, разве наш код не содержал среду выполнения? Когда данные изменяются, собственный узел DOM изменяется непосредственно через JavaScript, и нет никакой структуры для серии процессов сравнения и планирования (React Fiber). В этот момент вы можете спросить, действительно ли необходимо возвращаться к эпохе сокращения и сжигания, чтобы уменьшить размер пакета? Есть ли способ написать код с синтаксисом, близким к React и Vue, без включения среды выполнения фреймворка. Это именно то, что делает Svelte, принимая философию компилятора как фреймворка, помещая концепцию фреймворка во время компиляции, а не во время выполнения. Код приложения, который вы пишете в связке с такими инструментами, как Webpack и Rollup, будет преобразован непосредственно в собственный код JavaScript для манипулирования узлами DOM, так что bundle.js не содержит среды выполнения фреймворка. Итак, насколько Svelte может уменьшить размер пакета? Ниже приведеныRealWorldСтатистика по этому проекту:
Из приведенной выше диаграммы видно, что размер пакета Svelte составляет 1/4 от Vue и 1/20 от React! Из одних только этих данных можно сделать вывод, что оптимизация размера пакета фреймворком Svelte действительно великолепна.Неэффективное виртуальное домо
Какой? Виртуальный DOM не всегда очень эффективно это? В самом деле, Virtual DOM эффективным является недоразумением. Виртуальный DOM говорит одна из причин заключается в том, что он непосредственно не эффективный узел родной операции DOM, потому что это очень эффективность потребления. Когда изменение состояния компонента на него вычисляет настоящее обновление реальных данных изменяет вид, и меняется только «изменения необходимы» дифф узел DOM с помощью некоторого алгоритма. Используется Реагировать люди, вероятно, оценят React и не так эффективно, рамки иногда делают много полезной работы, которая находит свое отражение во многих компонентах не будет «никаких оснований» для повторной визуализации (повторного рендеринга). Обратите внимание на то, что повторная визуализации и для нативной операции DOM две разных вещей! Так называемый повторно вынести метод визуализации вашего определение класса компонента выполняется повторно, или ваша функция компоненты повторно выполняются. Компоненты повторно выводится, так Vitual DOM эффективный алгоритм основан на дифф, и обязательно иметь Diff повторно рендеринга компонентов для того, чтобы знать новое состояние и старые государственные собрания не изменились, поэтому для того, чтобы выяснить, какие DOM необходимо обновить. Можно сказать, что React Fiber не выходит из него, это не должно быть проблемой, не так ли? На самом деле, эта проблема архитектуры Fiber процесс повторного рендеринга и не помириться компоненты блокируют основной поток выполнения, повторно отдающую часть проблем все еще существует, и, в соответствии с обратной связью, после Реагировать Крючки из тяжелых компонентов, предоставляемых более частый. Именно потому, что сама структура трудно избежать ненужного рендеринга, React только позволяют использовать некоторые, такие как shouldComponentUpdate, PureComponent и useMemo АНИ сказать рамки, какие компоненты не должны быть повторно сгенерирована, но он также вводит ряд из шаблона кода (шаблонный). Если вы хотите узнать больше о проблемах виртуальных DOM, вы можете посмотретьvirtual dom is pure overheadЭта статья.
Так как же решить проблему неэффективного алгоритма Vitual DOM? Наиболее эффективным решением являетсяБез виртуального DOM! Фактически, проблема, которую необходимо решить как фреймворк, состоит в том, что при изменении данных соответствующие узлы DOM будут обновляться (реактивно).Виртуальный DOM должен сравнивать состояние старых и новых компонентов для достижения этой цели, и тем более эффективный способ на самом делеОбновляйте соответствующий узел DOM напрямую при изменении данных.:
if (changed.name) {
text.data = name;
}
Это подход, принятый Svelte. Svelte преобразует каждое изменение состояния в операцию соответствующего узла DOM при компиляции кода, чтобы узел DOM можно было быстро и эффективно обновлять при изменении состояния компонента. согласно сjs framework benchmarkСогласно статистике, Svelte работает лучше, чем React и Vue, при работе с некоторыми большими списками.
Что такое Свелте?
Svelte производитсяRollupJsСкомпилированный фреймворк, написанный автором Ричем Харрисом, студенты, которые не знакомы с RollupJs, могут посетить его официальный сайт, чтобы узнать о нем.На самом деле это инструмент для упаковки, похожий на Webpack. Фреймворк Svelte имеет следующие характеристики:
- Подобно использованию современных веб-фреймворков, таких как React и Vue, он позволяет разработчикам быстро разрабатывать веб-приложения с удобным пользовательским интерфейсом.
- Не используйтеVirtual DOM, и это не библиотека времени выполнения.
- Основываясь на концепции компилятора как фреймворка, он преобразует ваше приложение в нативную манипуляцию DOM во время компиляции.
- По умолчанию он поддерживает функцию области действия CSS, аналогичную модулям CSS, что позволяет избежать конфликтов стилей CSS.
- Встроенная поддержка анимации CSS.
- Чрезвычайно простое управление состоянием компонентов (без шаблонов) для разработчиков.
- Поддерживаются реактивные операторы.
- Чрезвычайно простое управление глобальным состоянием приложения, сама структура имеет свое собственное глобальное состояние, подобное Redux React и Vuex Vue.
- Поддержите контекст, чтобы избежать сверления реквизитов компонентов.
Самая большая разница между Svelte, Vue и React заключается в том, что у него есть много других полезных функций, помимо управления состоянием компонентов и отслеживания их рендеринга. Например, он изначально поддерживает область действия CSS и анимацию CSS. Если вы используете React или Vue, вам необходимо ввести сторонние библиотеки для достижения той же функции, а введение сторонних зависимостей увеличит стоимость обучения и обслуживания для разработчиков.
Создайте приложение книжного магазина с помощью Svelte
Далее мы с нуля создадим простой книжный магазин приложений на основе Svelte framework Я надеюсь, что с помощью этой демонстрации вы сможете понять некоторые основные концепции Svelte и освоить некоторые его основные способы использования, а также сможете использовать Svelte для создания более сложных приложений.
Функция приложения
Приложение «Книжный магазин» поддерживает следующие функции:
- Администратор вводит новую книгу
- Показать список книг книжного магазина
- Добавить книгу в корзину
- Отображение информации о данных корзины
Технические требования к учащимся
- Освойте базовое использование html, css и javascript
- Соответствующий опыт разработки с React или Vue является лучшим
Исходный код проекта можно найти в моемрепозиторий githubоказаться.
Строительство проекта
Сначала создайте новую папку проекта в нашей локальной среде разработки:
mkdir svelte-bookshop
Затем используйте официальные скаффолдинги svelte для инициализации нашего приложения:
npx degit sveltejs/template svelte-bookshop
cd svelte-bookshop
yarn
yarn dev
degitЭта команда напрямую скопирует файлы проекта на github в локальную папку.Используемый здесь адрес github проекта шаблона svelte/tempalte:это.以上命令成功运行后,访问http://localhost:5000Вы увидите следующий интерфейс:
Интерфейс очень прост, чтобы показать привет, мир, тогда давайте посмотрим на сгенерированную структуру каталогов проекта:Сгенерированный код в основном содержит следующую структуру каталогов файлов:- rollup.config.js — это файл конфигурации rollup, аналогичный webpack.config.js, в котором указывается, что входным файлом проекта является src/main.js.
- src, эта папка используется для хранения исходного кода нашего проекта, теперь есть только один основной входной файл main.js проекта и один файл компонента App.svelte.
- общедоступная папка, эта папка используется для хранения статических файлов проекта (index.html, global.css и favicon.png) и статических файлов, созданных при компиляции свертки (bundle.js и bundle.css в папке сборки и их их соответствующие исходные карты).
Далее давайте посмотрим на содержимое каждого файла в папке src.
src/App.svelte
<script>
export let name;
</script>
<main>
<h1>Hello {name}!</h1>
<p>Visit the <a href="https://svelte.dev/tutorial">Svelte tutorial</a> to learn how to build Svelte apps.</p>
</main>
<style>
main {
text-align: center;
padding: 1em;
max-width: 240px;
margin: 0 auto;
}
h1 {
color: #ff3e00;
text-transform: uppercase;
font-size: 4em;
font-weight: 100;
}
@media (min-width: 640px) {
main {
max-width: none;
}
}
</style>
Этот файл определяет компонент Svelte с именем App, Здесь следует отметить, что имя компонента не определено в файле App.svelte.Имя компонента определяется его именем файла.Все имена файлов компонентов Svelte заканчиваются на .svelte., файл компонента обычно состоит из следующих трех частей:
- Тег , здесь может быть размещен любой код JavaScript, относящийся к компоненту, например, определение состояния компонента или некоторые асинхронные запросы Ajax. В этом файле App.svelte не определено состояние локального компонента, но определена и экспортирована переменная имени. Для фреймворка Svelte экспорт переменной заключается в указании этой переменной в качестве внешнего параметра текущего компонента — props. Этот подход очень отличается от использования props в качестве первого параметра компонента в React, вы можете не привыкнуть к нему поначалу, но если вы привыкнете к нему позже, вы также можете влюбиться в этот способ написания.
- тег , здесь будет размещен код CSS, относящийся к компоненту. Обратите внимание, что CSS здесь действует локально (область действия), то есть стиль тега h1 в App.svelte будет действовать только для тега h1 в компоненте App и будет недействителен для других тегов h1 компонента. проект, включая дочерние узлы этого компонента. В частности, вы можете использовать инструмент отладки браузера, чтобы посмотреть на фактический стиль тега h1, чтобы понять:Как видно из рисунка выше, Svelte будет использовать некоторые случайные значения хеш-функции, чтобы отличать стиль компонента от стилей других компонентов при генерации кода.
- HTML-теги для компонентов. HTML-тег компонента может быть записан непосредственно в файле, например, HTML-часть компонента App:
<main>
<h1>Hello {name}!</h1>
<p>Visit the <a href="https://svelte.dev/tutorial">Svelte tutorial</a> to learn how to build Svelte apps.</p>
</main>
Самый внешний слой компонента приложения — это основной тег, основной тег имеет теги h1 и теги p, а тег h1 — это теги.Hello
Строка плюс строка вставки (интерполяция), заключенная в фигурные скобки, которая должна быть записана в React JSX какHello ${name}
, все они указывают, что строка в этой позиции является содержимым имени переменной. Что касается этой переменной имени, это внешний параметр, который мы определили с экспортом выше.
В общем, Svelte помещает весь код JavaScript, CSS и HTML, связанный с компонентом, в один и тот же файл, что немного похоже на Vue, но содержит меньше кода шаблона, чем Vue.
src/main.js
import App from './App.svelte';
const app = new App({
target: document.body,
props: {
name: 'world'
}
});
export default app;
Содержимое этого файла очень простое, то есть монтирует только что определенный компонент приложения к телу целевого узла и предоставляет компоненту приложения значениеworld
параметр имени. Этот код работает так же, как функция ReactDOM.render в React.
Далее давайте посмотрим, как выглядит сгенерированный статический код.
public/build/bundle.js
Давайте сначала посмотрим на сгенерированный основной файл JavaScript bundle.js, Поскольку исходный файл относительно большой, я перехватил только ключевую часть:
/* src/App.svelte generated by Svelte v3.16.4 */
const file = "src/App.svelte";
function create_fragment(ctx) {
let main;
let h1;
let t0;
let t1;
let t2;
let t3;
let p;
let t4;
let a;
let t6;
const block = {
c: function create() {
main = element("main");
h1 = element("h1");
t0 = text("Hello ");
t1 = text(/*name*/ ctx[0]);
t2 = text("!");
t3 = space();
p = element("p");
t4 = text("Visit the ");
a = element("a");
a.textContent = "Svelte tutorial";
t6 = text(" to learn how to build Svelte apps.");
attr_dev(h1, "class", "svelte-1tky8bj");
add_location(h1, file, 5, 1, 46);
attr_dev(a, "href", "https://svelte.dev/tutorial");
add_location(a, file, 6, 14, 83);
add_location(p, file, 6, 1, 70);
attr_dev(main, "class", "svelte-1tky8bj");
add_location(main, file, 4, 0, 38);
},
l: function claim(nodes) {
throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option");
},
m: function mount(target, anchor) {
insert_dev(target, main, anchor);
append_dev(main, h1);
append_dev(h1, t0);
append_dev(h1, t1);
append_dev(h1, t2);
append_dev(main, t3);
append_dev(main, p);
append_dev(p, t4);
append_dev(p, a);
append_dev(p, t6);
},
p: function update(ctx, dirty) {
if (dirty[0] & /*name*/ 1) set_data_dev(t1, /*name*/ ctx[0]);
},
i: noop,
o: noop,
d: function destroy(detaching) {
if (detaching) detach_dev(main);
}
};
dispatch_dev("SvelteRegisterBlock", {
block,
id: create_fragment.name,
type: "component",
source: "",
ctx
});
return block;
}
Этот код соответствует компоненту приложения, который мы только что определили.create_fragment
метод примет объект контекстаctx
параметр и возвращает блочный объект, представляющий компонент.
block
Этот объект в основном содержит следующие четыре важных метода.c
(Создайте),m
(устанавливать),p
(обновление) иd
(разрушать).
с (создать)
function create() {
main = element("main");
h1 = element("h1");
t0 = text("Hello ");
t1 = text(/*name*/ ctx[0]);
t2 = text("!");
t3 = space();
p = element("p");
t4 = text("Visit the ");
a = element("a");
a.textContent = "Svelte tutorial";
t6 = text(" to learn how to build Svelte apps.");
attr_dev(h1, "class", "svelte-1tky8bj");
add_location(h1, file, 5, 1, 46);
attr_dev(a, "href", "https://svelte.dev/tutorial");
add_location(a, file, 6, 14, 83);
add_location(p, file, 6, 1, 70);
attr_dev(main, "class", "svelte-1tky8bj");
add_location(main, file, 4, 0, 38);
}
Функция этой функции состоит в том, чтобы сгенерировать (создать) некоторые собственные узлы DOM, связанные с компонентом приложения, и добавить к ним некоторые метаданные.
м (гора)
function mount(target, anchor) {
insert_dev(target, main, anchor);
append_dev(main, h1);
append_dev(h1, t0);
append_dev(h1, t1);
append_dev(h1, t2);
append_dev(main, t3);
append_dev(main, p);
append_dev(p, t4);
append_dev(p, a);
append_dev(p, t6);
}
Функция этой функции заключается в монтировании тех DOM-узлов, сгенерированных функцией c.
р (обновление)
function update(ctx, dirty) {
if (dirty[0] & /*name*/ 1) set_data_dev(t1, /*name*/ ctx[0]);
}
Функция p будет обновлять свойства соответствующего узла DOM при обновлении контекста ctx. Вероятно, когда контекст изменится, проверьте, изменилось ли имя переменной, и обновите узел DOM, если он изменится.
д (уничтожить)
function destroy(detaching) {
if (detaching) detach_dev(main);
}
Функция d используется для удаления компонента приложения.
После прочтения кода, сгенерированного Svelte, я думаю, у вас должно быть более глубокое понимание таких концепций, как «Компилятор как фреймворк», о котором я упоминал в начале статьи.Разница между Svelte и React (и Vue похожа) заключается в том, что:После того, как приложение React упаковано, оно также сохраняет код вызова функций фреймворка, таких как React.createElement, setState и т. д. После компиляции Svelte код фреймворка будет преобразован в код для работы с собственными узлами DOM.
Приблизительно разобравшись с организационной структурой проекта, давайте начнем формальную сборку приложения для книжного магазина.
определение компонента
HTML markup
Сначала давайте создадим компонент карты, отображающий конкретную информацию о книге, создадим новый файл BookCard.svelte в папке src и определим HTML-разметку компонента карты:
// src/BookCard.svelte
<div>
<h1>title</h1>
<div>price</div>
<div>description</div>
<button>添加到购物车</button>
</div>
Затем используйте компонент BookCard внутри компонента App.svelte:
// src/App.svelte
<script>
import BookCard from "./BookCard.svelte";
</script>
<style>
...
</style>
<main>
<h1>Welcome to my online bookstore!</h1>
<section>
<BookCard />
</section>
</main>
Метод использования пользовательского компонента очень прост: сначала импортируйте только что определенный компонент BookCard в тег script, а затем пропишите компонент в HTML-разметке компонента App.Синтаксис такой же, как у JSX.Затем снова посмотрите на содержимое страницы:
CSS
Хотя компонент BookCard отсутствует, нам нужно определить CSS, чтобы он выглядел лучше:
// src/BookCard.svelte
<style>
.card {
text-align: left;
border-radius: 5px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.26);
padding: 10px;
}
h1 {
font-size: 20px;
}
h2 {
font-size: 15px;
color: #999;
}
button {
background-color: #ff3e00;
color: white;
border-radius: 5px;
cursor: pointer;
border: none;
}
</style>
<div class="card">
<h1>title</h1>
<h2>price</h2>
<p>description</p>
<button>添加到购物车</button>
</div>
Способ определения стиля для компонента заключается в создании нового тега стиля и написании стиля, связанного с компонентом, в этом теге.Обратите внимание, что стиль здесь действителен только для элементов в компоненте и не повлияет на стили компонентов. другие компоненты. После добавления стилей интерфейс должен выглядеть так:
определение реквизита
Конкретная информация о книге должна быть указана входящим реквизитом.Реквизит компонента Svelte должен быть указан при экспорте, а указанная переменная реквизита может использоваться непосредственно компонентом.:
// src/BookCard.svelte
<script>
export let title;
export let price;
export let description;
</script>
<style>
...
</style>
<div class="card">
<h1>title</h1>
<h2>price</h2>
<p>description</p>
<button>添加到购物车</button>
</div>
использование переменных
Определенная и введенная переменная может использоваться непосредственно в HTML-разметке компонента. Конкретное использование состоит в том, чтобы ссылаться на переменную с помощью фигурных скобок в разметке. Конкретный код:
// src/BookCard.svelte
<script>
export let title;
export let price;
export let description;
</script>
<style>
...
</style>
<div class="card">
<h1>{title}</h1>
<h2>${price}</h2>
<p>{description}</p>
<button>添加到购物车</button>
</div>
Передача параметров компонента
Затем в приложении родительского компонента передайте параметры, требуемые BookCard, компоненту:
// src/App.svelte
<script>
...
let title = "JavaScript高级编程";
let price = 99.0;
let description = "一起来学习JavaScript啊";
</script>
<style>
...
</style>
<main>
<h1>Welcome to my online bookstore!</h1>
<section>
<BookCard title={title} price={price} description={description} />
</section>
</main>
В это время входящим параметром должно быть содержимое карточки книги:
Для передачи параметров компонента Svelte также предоставляет следующий более удобный способ записи:// src/App.svelte
<main>
<h1>Welcome to my online bookstore!</h1>
<section>
<BookCard {title} {price} {description} />
</section>
</main>
Введите информацию о книге
В книжном магазине администраторы должны иметь возможность вводить новые книги, поэтому мы добавляем простую форму в компонент приложения, чтобы пользователи могли вводить данные:
// src/App.svelte
<script>
...
</script>
<style>
....
</style>
<main>
<h1>Welcome to my online bookstore!</h1>
<section>
<h2>Add new book</h2>
<label for="title">Title</label>
<input type="text" id="title" value={title} />
<label for="price">Price</label>
<input type="number" id="price" value={price} />
<label for="description">Description</label>
<textarea rows="3" id="description" value={description} />
</section>
<section>
<BookCard {title} {price} {description} />
</section>
</main>
Мы создали несколько входных тегов для компонента App и указали значения этих входных тегов в качестве переменных, которые мы определили ранее, В это время мы попытались изменить содержимое поля ввода:
Хотя начальным значением поля ввода является значение, соответствующее переменной, значение переменной не будет меняться со значением поля ввода, то есть их значения не будут «связаны». привязка данных, мы можем добавить событие прослушивателя в поле ввода.привязка события
Мы можем добавить прослушиватели событий в DOM, используя ключевое слово on и имя события., следующий код будет контролировать ввод поля вводаinput
мероприятие:
<script>
...
let title = "JavaScript高级编程";
...
function handleTitleChange(event) {
title = event.target.value;
}
</script>
<style>
...
</style>
<main>
<h1>Welcome to my online bookstore!</h1>
<section>
<h2>Add new book</h2>
<label for="title">Title</label>
<input type="text" id="title" value={title} on:input={handleTitleChange} />
...
</section>
</main>
В это время, когда мы снова изменим значение ввода, мы обнаружим, что содержимое в карточке также изменилось, что указывает на то, что мы успешно изменилиtitle
Значение переменной:
Автоматическая двусторонняя привязка данных
Однако, если каждый входной тег должен вручную добавлять прослушиватель событий, наш код будет иметь много шаблонного кода.Чтобы решить эту проблему,Svelte позволяет нам напрямую использовать ключевое слово bind, чтобы добавить свойства, которые будут привязаны для двусторонней привязки данных.:
// src/App.svelte
<script>
...
let title = "JavaScript高级编程";
let price = 99.0;
let description = "一起来学习JavaScript啊";
</script>
<style>
...
</style>
<main>
<h1>Welcome to my online bookstore!</h1>
<section>
<h2>Add new book</h2>
<label for="title">Title</label>
<input type="text" id="title" bind:value={title} />
<label for="price">Price</label>
<input type="number" id="price" bind:value={price} />
<label for="description">Description</label>
<textarea rows="3" id="description" bind:value={description} />
</section>
...
</main>
В это время мы можем удалить начальное значение каждой переменной:
// src/App.svelte
<script>
let title = "";
let price = 0;
let description = "";
</script>
На данный момент поле ввода нашей страницы и все переменные «связаны»:
Показать список книг
В нашем книжном магазине должно быть более одной книги, и мы должны использовать массив для хранения всех книг:
// src/App.svelte
<script>
...
let books = [];
...
</script>
Затем мы добавляем кнопку отправки во вновь добавленную форму.После того, как пользователь заполнит информацию о книге и нажмет «Отправить», будет создан новый объект книги, который будет добавлен в список книг:
<script>
...
let books = [];
function handleAddBook() {
books = books.concat({ title, price, description });
title = "";
price = 0;
description = "";
}
...
</script>
<style>
...
button {
background-color: #ff3e00;
color: white;
border-radius: 5px;
cursor: pointer;
border: none;
}
...
</style>
<main>
<h1>Welcome to my online bookstore!</h1>
<section>
<h2>Add new book</h2>
<label for="title">Title</label>
<input type="text" id="title" bind:value={title} />
<label for="price">Price</label>
<input type="number" id="price" bind:value={price} />
<label for="description">Description</label>
<textarea rows="3" id="description" bind:value={description} />
<div>
<button on:click={handleAddBook}>add book</button>
</div>
</section>
...
</main>
Показать данные списка
Мы можем использовать каждый блок для отображения данных из списка книг.:
// src/App.svelte
<script>
....
let books = [];
function handleAddBook() {
books = books.concat({ title, price, description });
title = "";
price = 0;
description = "";
}
</script>
<main>
...
<section>
{#each books as book}
<BookCard
title={book.title}
price={book.price}
description={book.description} />
{/each}
</section>
</main>
Вы также можете деконструировать содержимое рекурсивного объекта напрямую, когда каждый блок определен, приведенный выше код становится:
// src/App.svelte
...
<section>
{#each books as { title, price, description }}
<BookCard {title} {price} {description} />
{/each}
</section>
...
После изменения кода ваша страница может войти в новую книгу и отобразить список книг:
функция корзины
Для начала нам нужно добавить событие клика на кнопку компонента BookCard: когда пользователь нажмет кнопку карточки книги, книга будет добавлена в корзину. Для достижения этого эффекта мы можем определить кнопку BookCardhandleAddBookпараметр, который предоставляется внешним компонентом,handleAddBookФункция вызывается, когда пользователь нажимает кнопку BookCard и добавляет книгу в корзину. код показывает, как показано ниже:
// src/BookCard.svelte
<script>
...
export let handleAddToCart;
</script>
<style>
...
</style>
<div class="card">
<h1>{title}</h1>
<h2>${price}</h2>
<p>{description}</p>
<button on:click={() => handleAddToCart(title)}>添加到购物车</button>
</div>
// src/App.svelte
<script>
...
let booksInCart = [];
function handleAddToCart(title) {
let bookNeededToBeAdded = books.find(book => book.title == title);
booksInCart = booksInCart.concat(bookNeededToBeAdded);
}
</script>
<style>
...
</style>
<main>
...
<section>
<h2>购物车</h2>
{#each booksInCart as { title, price }}
<div>名称: {title}, 价钱: {price}</div>
{/each}
</section>
<section>
<h2>书单</h2>
{#each books as { title, price, description }}
<BookCard {title} {price} {description} {handleAddToCart} />
{/each}
</section>
</main>
На этом этапе мы видим нашу корзину:
Условное суждение
Svelte может использовать блок if для отображения различного контента в зависимости от различных условий., мы можем показать пользователю пустое состояние, когда корзина пуста:
// src/App.svelte
...
<section>
<h2>购物车</h2>
{#if booksInCart.length === 0}
<p>购物车空的哦~</p>
{:else}
{#each booksInCart as { title, price }}
<div>名称: {title}, 价钱: {price}</div>
{/each}
{/if}
</section>
...
В этот момент интерфейс становится:
Показать статистику корзины
Мы добавим в книжный магазин функцию, помогающую пользователям подсчитывать книги в корзине, которая может отображать общее количество книг и общую сумму в корзине.Код выглядит следующим образом:
// src/App.svelte
<script>
...
let booksInCart = [];
let booksNumInCart = booksInCart.length;
let totalCheckoutPrice = booksInCart.reduce(
(sum, book) => sum + book.price,
0
);
...
</script>
...
<section>
<h2>购物车</h2>
<div>书本总数:{booksNumInCart}</div>
<div>订单金额:{totalCheckoutPrice}</div>
...
</section>
...
В это время, когда мы работаем с интерфейсом, мы обнаруживаем, что статистические данные не меняются при изменении данных корзины:
Причина, по которой данные не изменились, заключается в том, что мы не меняли их вручную каждый раз, когда добавляли книгу в корзину.booksNumInCart
а такжеtotalCheckoutPrice
ценность . Однако, если вам нужно вручную вести статистику при изменении данных корзины, код станет некрасивым.
реактивное определение
Для этого случая Svelte предоставляетреактивное определениеметод (реактивного назначения) для представления этих данных связи,Конкретный метод заключается в использовании$
Символы определяют переменные вместо let, вот код:
<script>
...
let booksInCart = [];
$: booksNumInCart = booksInCart.length;
$: totalCheckoutPrice = booksInCart.reduce(
(sum, book) => sum + book.price,
0
);
...
</script>
так когдаbooksInCart
При изменении этих данныхbooksNumInCart
а такжеtotalCheckoutPrice
Эти две переменные автоматически пересчитываются.
В это время, если мы снова поработаем с интерфейсом, мы обнаружим, что статистические данные автоматически изменятся с изменением данных корзины покупок:
Релиз пакета
Наконец, давайте упакуем приложение для книжного магазина, которое мы только что написали. Запустите следующую команду в корневом каталоге, чтобы упаковать код:
yarn build
После завершения упаковки проверьте размер полученного файла:
➜ build git:(master) ls -lh
total 152
-rw-r--r-- 1 sean staff 659B 12 17 14:17 bundle.css
-rw-r--r-- 1 sean staff 3.9K 12 17 14:17 bundle.css.map
-rw-r--r-- 1 sean staff 7.6K 12 17 14:17 bundle.js
-rw-r--r-- 1 sean staff 57K 12 17 14:17 bundle.js.map
Видно, что bundle.js всего меньше 8 тыс., а фреймворк React оценивается в 100 тыс.+ С этой точки зрения фреймворк Svelte действительно уменьшил объем генерируемого кода.
Суммировать
Наша простая система книжного магазина (книжный магазин), вероятно, реализует эти функции.Теперь давайте подытожим базовые знания фреймворка Svelte, полученные при разработке проекта:
- определение компонента - определение компонента
- Использование переменных — использование переменных
- определение и передача реквизита - определение и передача реквизита
- прослушивание событий - прослушивание событий
- привязка данных - привязка данных
- Условное суждение - если условие
- Отображение списка данных - каждый блок
На самом деле фреймворк Svelte имеет множество полезных функций, о которых я не упомянул, например:
- доставка событий - переадресация событий
- Функции жизненного цикла - функции жизненного цикла
- Глобальное управление состоянием - магазины
- управление контекстом - контекст
- CSS-анимация — css-анимация
- ...
Из-за ограниченного объема статьи я не рассмотрел здесь все свойства Svelte.Если вам интересно, вы можете взглянуть на svelteОфициальный учебник.
Некоторые из моих личных мыслей о фреймворке Svelte
Я лично считаю, что из-за различных проблем Virtual DOM идея компилятора как фреймворка должна быть тенденцией в развитии фронтенд-фреймворков. Хотя функции, реализованные в настоящее время в Svelte, очень хороши, на данный момент я думаю, что у него все еще есть следующие проблемы:
- Масштабируемость - Масштабируемость. Хотя среда выполнения, которая поставляется с такими фреймворками, как React и Vue, будет увеличивать пакет bundle.js, загружаемый на первом экране, когда проект становится все больше и больше, среда выполнения фреймворка будет занимать все меньшую и меньшую долю пакета bundle.js. Наоборот, поскольку инкапсуляция кода, генерируемого Svelte, не так хороша, как у React и Vue, не будет ли он накапливать много повторяющегося кода в больших проектах? В настоящее время мы должны рассмотреть, существует ли порог, при котором код, сгенерированный Svelte, больше, чем код, сгенерированный React и Vue. Конкретного ответа на этот вопрос пока нет, и ответ можно будет дать только тогда, когда будущие поколения будут его практиковать.Если вам интересно, вы можете взглянуть на авторскуюОбсуждение на гитхабе.
- Экосистема - Экология. Как фреймворк, который стал популярен только недавно, экология Svelte далека от React и Vue, популярных уже столько лет, поэтому я думаю, что Svelte не может поколебать статус React и Vue в настоящее время. Но вызовет ли Svelte экологический взрыв из-за своей продвинутой природы? Мы можем подождать и посмотреть.
Но одно можно сказать наверняка: Svelte будет сиять в некоторых менее производительных встроенных операционных системах из-за его гораздо меньших преимуществ, чем React, Vue и Angular из-за кода, сгенерированного в некоторых несложных проектах.
Полезные ссылки для изучения Svelte
Продолжайте обращать внимание на мои технические тренды
Я атакующий зеленый лук. Сейчас я руководитель группы в компании, занимающейся электронной коммерцией. Следуйте за мной, и я буду развиваться вместе, чтобы стать полноценным инженером самостоятельно!
Нажмите здесь, чтобы узнать адрес блога команды:space-fe blogs
Подпишитесь на мою личную общедоступную учетную запись, чтобы получать новейшие технологии!