如何构建一个简单的 Svelte JS 应用
由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!
作者:奥宾娜·埃库诺✏️
在 JavaScript 领域,每天都有新的框架涌现,这些进步背后的理念几乎总是相同的,只是在一些方面进行了非常显著的改进。现代的基于组件的框架包括ReactJS、VueJS、EmberJS、Angular等等。
在本文中,我们将介绍其中一个名为SvelteJS 的新框架。它基于 HTML、CSS 和 JavaScript 的基础知识,为构建 Web 平台提供了一种独特且易于理解的方法。
Svelte 提供了一个中间平台,既可以帮助你入门基础知识,又可以让你熟悉组件驱动开发、作用域 CSS 与层叠 CSS、模板、声明式函数等现代概念。
先决条件
在深入探讨之前,本文需做出以下假设:
- 您的计算机上已安装Node.js ≥v6。
- 您的机器上已安装npm 。
- 熟悉 HTML、CSS 和 JavaScript
- 对ReactJS等基于组件的框架有基本的了解固然好,但并非必需。
Svelte 与基于组件的框架之间的区别
Svelte 对编程新手来说更容易理解,它避免了陷入热重载和组件的复杂世界,因为它允许对 DOM 进行类型操作。Svelte 会将所有生成的文件编译成一个单独的文件(bundle.js)。Svelte 是一个框架,这意味着它不使用虚拟 DOM,而是编写代码,在应用程序状态改变时精确地更新 DOM。
使用 Svelte 构建书店应用程序
入门
有多种方法可以启动并运行 Svelte 项目。您可以点击此处了解更多入门方法。本文将使用degit ,这是一个软件脚手架工具。首先,运行以下命令:
- npx degit sveltejs/template {项目名称}: 在本例中,我将其命名为 Book-app-svelte
npx degit sveltejs/template Book-app-svelte
- 进入项目目录
- 运行 npm install
- 运行应用程序
npm run dev
设置完成后,在 中main.js,我们应该看到一个“hello world”渲染到 中app.svelte——此时应该注意 Svelte 中的组件是以 .svelte.svelte扩展名保存的。
import App from './App.svelte';
const app = new App({
target: document.body,
props: {
name: 'world'
}
});
export default app;
上面的代码展示了一个简单的设置,其中应用程序组件接受一个名为 name 的 prop,并指向 HTML 文件中的一个位置。
我们app.svelte可以看到某种 VueJS 格式:
<script>
export let name;
</script>
<style>
h1 {
color: purple;
}
</style>
<h1>Hello {name}!</h1>
这里main.js通过导出名称变量来处理,以便可以从外部对其进行操作。
创建动态图书组件
在创建组件时,SvelteJS 有几点值得注意:
- 样式的作用域仅限于组件内部——因此,
h1在一个组件中设置的样式不会影响另一个组件中的样式。 - 我们可以定义动态连接的函数。
在本节中,我们将探讨如何使用 Svelte 创建动态事件,以及如何将book.svelte组件与props 连接app.svelte并传递 props。
第一步是设置书籍组件并导出变量,这些变量可以从父标签中设置app.svelte:
<script>
export let bookTitle;
export let bookPages;
export let bookDescription;
</script>
<style>
div{
margin: 1rem;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.26)
}
h1{
font-size: 1.25rem;
margin: 0.25rem 0;
}
h2{
font-size: 1rem;
margin: 0.25rem 0;
color: aqua;
}
p{
margin: 0.25rem 0;
}
button{
font : larger;
padding: 0.15rem 0.5rem;
background-color: #1b1a1a;
border: 1px solid aliceblue ;
cursor: pointer;
color: white;
}
</style>
<div>
<h1> {bookTitle} </h1>
<h2> {bookPages}</h2>
<p> {bookDescription}</p>
<button> Add </button>
</div>
从上面的代码块可以看出,有一些变量被动态地传递给了标签div。它们的值来自接下来app.svelte我们将看到的,大部分动态操作都发生在这里。
我们app.svelte已经导入了书籍组件,我们将在这里进行大量的动态操作。
<script>
import Book from './book.svelte'
let title = '';
let pages = 0;
let description = '';
function setTitle(event){
title = event.target.value;
}
</script>
<style>
h1 {
color: purple;
}
section{
margin: auto;
width :30rem;
}
label,input,textarea{width: 100%}
</style>
<section>
<div>
<label for="title">Title</label>
<input type="text" id="title" value={title} on:input={setTitle}/>
</div>
<div>
<label for="pages"> pages</label>
<input type="number" id="price" value={pages} bind:value={pages}/>
</div>
<div>
<label for="description">Description</label>
<textarea rows="3" id="description" bind:value ={description}/>
</div>
</section>
<Book bookTitle={title} bookPages={pages} bookDescription={description}/>
从上面的代码示例中,我们可以看到,在 script 标签内,我们也设置了一些变量为空“ ”。这些值会自动更新。我们还可以注意到一个函数setTitle,该函数用于设置标题,以指向在 script 标签内调用它的对象on:。
请注意,我们调用函数时没有使用括号,因为我们不希望它立即执行。相反,我们试图设置一个引用,以便 Svelte 可以在每次按键时调用该函数。
在 Svelte 中,我们使用 `<script>` 标签on:来添加事件监听器。我们可以用它来监听输入事件,而花括号则用于显示动态输入。由于我们使用的函数采用了双向绑定,因此我们可以将其应用于其他标签。` bind:<script>` 标签会先绑定 `value` 属性,然后再绑定到 `price` 变量。我们对 `description` 属性也采用了类似的方法。
最后,在将参数传递回Book标签时,我们会更新书籍组件中导出的 props。我们通过使用花括号动态传递 title、pages 和 descriptions 的值来实现这一点{}。
显示书籍信息
现在我们已经实现了输入值后卡片更新的功能,下一步是确保能够向书店添加书籍。首先,我们需要将按钮设为独立组件,以便在其他两个组件中使用它。为此,我们创建了一个独立组件,button.svelte并分别将其导入到书籍组件和应用组件中。
<style>
button{
font : larger;
padding: 0.15rem 0.5rem;
background-color: #1b1a1a;
border: 1px solid aliceblue ;
cursor: pointer;
color: white;
}
</style>
<button on:click >
<slot/>
</button>
您可能会注意到on:click按钮标签中的一个属性,这是用于在按钮的原始调用中触发事件监听器,以便其他导入能够真正与 onclick 事件一起工作。
例如:app.svelte
<Button on:click={addBook}>ADD Book</Button>
这会调用一个addBook函数,该函数允许按钮动态地向数组中添加书籍:
let books =[]
function addBook(){
const newBook = {
title : title,
pages : pages,
description: description
};
books = books.concat(newBook)
}
上述代码位于 script 标签内,其作用是调用表单中书籍的所有属性并将它们连接起来。我们使用 `<div>` 是concat因为 `push` 方法不会改变书籍变量本身,它只会改变数组,而赋值concat才会触发变量的改变。
我们现在有一个书籍数组,它可以根据条件显示,这是通过 Svelte 提供的特殊标记实现的:
{#if books.length === 0}
<p>
Add a new book
</p>
{:else}
{#each books as book}
<Book bookTitle={book.title} bookPages={book.pages} bookDescription={book.description}/>
{/each}
{/if}
这样做会提示用户添加新书,然后将每个新添加的书籍块显示为一张新卡片:
加上书价
为了实现这一点,我们需要创建另一个名为 `<book>` 的组件purchase.svelte。在 `<script>` 标签中,我们希望导出 `books` 变量,以便可以通过 `<book>` 标签更新它,方法是将信息作为 props 传递给 `<book>` 标签app.svelte。
我们在脚本中app.svelte添加了一个空数组来保存已购买的书籍。现在,我们如何将书籍添加到这些购买记录中呢?我们将使用书籍组件中的购买按钮,然后将函数添加purchaseBook到脚本中,并使用绑定到该按钮on:{purchaseBook}。
然后我们使用 Svelte 自定义库中的 create-dispatch 函数。
on:buy = {purchaseBook}然后,我们可以通过在函数中添加此事件分发来将该函数链接到 Book 标签purchaseBook。
function purchaseBook(event){
const selectedTitle= event.detail;
purchases = purchases.concat({
...books.find(book => book.title === selectedTitle )
});
}
结论
本文通过创建一个书店示例,尝试理解 Svelte 的基本用法。希望这篇文章能帮助你了解 SvelteJS 的强大功能,并展示如何利用它创建出色的应用程序。这里是示例的链接。祝你编程愉快!
编者按:发现本文有误?您可以在这里找到正确版本。
插件:LogRocket,一款用于 Web 应用的 DVR

LogRocket是一款前端日志工具,可让您重现问题,如同在您自己的浏览器中发生一样。无需猜测错误原因,也无需用户提供屏幕截图和日志转储,LogRocket 即可让您重现会话,快速了解问题所在。它与任何框架的应用程序完美兼容,并提供插件来记录来自 Redux、Vuex 和 @ngrx/store 的额外上下文信息。
除了记录 Redux 操作和状态之外,LogRocket 还会记录控制台日志、JavaScript 错误、堆栈跟踪、包含标头和正文的网络请求/响应、浏览器元数据以及自定义日志。它还会对 DOM 进行插桩,记录页面上的 HTML 和 CSS,即使是最复杂的单页应用程序,也能生成像素级精确的视频。
免费试用。
这篇文章《如何构建一个简单的 Svelte JS 应用》最初发表在LogRocket 博客上。
文章来源:https://dev.to/bnevilleoneill/how-to-build-a-simple-svelte-js-app-2090



