Svelte在服务器端工作,将你的应用程序编译成优化的JavaScript。让我们快速浏览一下这个快速、反应式组件框架。
软件架构师,InfoWorld |

思维导图
随着2021年接近一半的时间,JavaScript的黄金时代仍在继续。当前章节中最令人兴奋的角色之一是Svelte框架。这篇文章给你介绍了创建Svelte项目和使用一些简单的UI元素的基本知识。
与目前以React、Angular和Vue为代表的群体思维截然不同的是,Svelte在服务器端工作,将你的应用程序编译成优化的JavaScript。这意味着,Svelte需要建立一个构建管线。
虽然建立一个构建管道可能看起来是额外的工作,但事实上,在React、Angular或Vue中,所有真正的开发都需要某种形式的构建管道(如create-react-app或Webpack配置)。另外,设置Svelte环境可以快速获得热部署开发模式等功能。
Svelte设置
让我们直接进入,建立一个简单的构建环境。你将会使用npx和degit来创建一个启动模板。使用清单1中的步骤。
清单1.初始模板
npx degit sveltejs/template infoworld-svelte
cd infoworld-svelte
npm install
npm run dev
在这一点上,启动程序将在localhost:5000运行;在你的浏览器中查看。在你的代码编辑器或IDE中打开/infoworld-svelte文件夹。在/src目录下有两个感兴趣的源文件。App.svelte和main.js。这两个文件共同定义了你在浏览器中看到的内容。
注意:所有的代码都可以在这个 repo 中找到。
如果你使用Visual Studio Code,有一些有用的(免费)Svelte扩展,提供语法高亮和自动完成。
要找到它们,请到左边的扩展工具中,在搜索栏中输入 "ext:svelte"。
main.js是该应用程序的主要入口点。如清单2所示,它在第一行导入了App.svelte 。
清单2.main.js
import App from './App.svelte';
清单2显示了一些关于Svelte如何工作的有趣内容。从App.svelte 中导出的数据已被转化为一个对象,并通过new App({...}) 的调用将其实例化。
App 对象被配置了几个参数。这些参数用于为Svelte对象的参数提供值。target param是一个内置属性,Svelte用它来告诉应用程序的根在哪里(类似于ReactDOM.render 的第二个参数)。
现在看一下 App.svelte.这有Svelte中组件语法的肉,它结合了JavaScript、标记和CSS这三个元素,分别是script 、main 、style 标签。这些内容与main.js中的实例化所提供的参数一起被组合在一起, into a component. Note that the `main` tag could be any valid HTML tag.
Notice that Svelte uses variable tokens in the same syntax as the other frameworks: `<h1>Hello {name}!</h1>`. Notice also that this variable, whose value is supplied by the params in main.js, is exported in the script section: `export let name;`. This could also be done directly in the script. To see what I mean, change this line to `let name = "InfoWorld";`, eliminating the export entirely. The point being, there is nothing magical or required about parameterizing the `App` object via main.js. It is just a supported feature for organizing things.
Since you are running in dev mode, the change will be reflected immediately. The browser will now show the new greeting, “Hello InfoWorld!”
The are many features necessary to building sophisticated UIs. Among the most essential are iterators and object handling. Let’s have a look by adding the code seen in Listing 3.
Listing 3. Iterating over an array of objects` `
<script> let quotes = [ {author:"Emerson", quote:"To be great is to be misunderstood."}, {author:"James", quote:"The art of being wise is the art of knowing what to overlook."}, {author:"Thoreau", quote:"That government is best which governs least."} ];</script><main> <ul> {#each quotes as { quote, author }, i} <li>{i} - {quote}</li> {/each} </ul></main>
The basic syntax is the `{#each}` tag. This is used to reference the variable `quotes`. The elements of this array variable are then exposed (via [destructuring](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#object_destructuring)) to the internals of the tag, along with an iterator counter `i`. These exposed variables are then referenced with the same token syntax as any other variable. If you are familiar with another framework, I think you’ll agree the syntax is very concise here.
Event handling in Svelte
Adding handlers like `onClick` is similarly easy. You can add one to the list items as seen in Listing 4.
Listing 4. Adding an onClick handler
<script>...function click(){ alert("ok"); }...</script><main>...<li on:click="{click}">{i} - {quote}</li> ...</main>
`` `The event handling syntax is fairly self-explanatory. You can also pass in params to the handler by wrapping the handler function, like so:` ``
<li on:click="{() => click(author)}">{i} - {quote}</li>
`` `This can be used by the handler function:` ``
function click(author){ alert("hello from " + author); }
`` `Svelte components and inputs` ``
`` `Now get a taste for the component system, along with two-way binding of input elements. You are adding a new component that will create quotes to add to the list. First, create a new file called /src/AddQuote.svelte and paste in the contents of Listing 5.` ``
`` `Listing 5. The AddQuote component (event dispatch and input binding)` ``
<script> import { createEventDispatcher } from 'svelte'; const dispatch = createEventDispatcher(); // create dispatcher let author = ""; let quote = ""; function onAdd(author, quote){ dispatch('quote', { // use dispatcher author: author, quote: quote }); }</script><main> <div class="add-quote"> <h2>New Quote</h2> <div>Author: <input bind:value={author} placeholder="Author"></div> <div>Quote: <input bind:value={quote} placeholder="Quote"></div> <button on:click={()=>{onAdd(author, quote)}}>Add It!</button> </div></main>
`` `Component events` ``
``` ``Several new concepts are introduced here. First is component events. These are events that components can raise and that are handled by other components just like DOM events. The basic process is to import the `createEventDispatcher` from Svelte, then use it to create a dispatcher function. This dispatcher function is called and passed the name of the event (`'quote'`) and the content of the event (in this case, the new quote information).`` ```
``` ``This event is then handled by our `App` component, as we’ll see in a moment.`` ```
`` `Input bindings` ``
``` ``Binding the HTML inputs, aka two-way bindings, is also simple. You can see this in the `main` element of Listing 5. Notice the `bind:value` attributes on the input elements. These reference the variables to which the input will be bound—in this case, the author and quote variables.`` ```
``` ``You then use a button element with an `onClick` handler to raise the dispatch event in the `onAdd` function.`` ```
`` `Catching custom events in Svelte` ``
``` ``Back in the App.svelte file, you can use the `AddQuote` component as seen in Listing 6.`` ```
`` `Listing 6. Using the AddQuote component` ``
<script>... function onAddQuote(event){ quotes = [...quotes, {author:event.detail.author, quote:event.detail.quote}]; }</script>...<main>...<AddQuote on:quote={onAddQuote}></AddQuote>...</main>
``` ``Listing 6 shows how, in the markup, you use `on:quote` to listen for the custom quote event and send it to the handler function, `onAddQuote`, which is defined in the script section. This function is handed the event, which contains the event object we sent in `AddQuote` in the `event.detail` member.`` ```
``` ``From there it’s a simple matter of updating the data in the `quotes` array to reflect the new item. Note though that you must update the array with an assignment, or Svelte won’t notice the change. In other words, just using `Array.push` won’t trigger the update. (This is similar to other reactive frameworks.)`` ```
`` `API fetching in Svelte` ``
`` `As a quick extra bonus, let’s see how quickly we can add a remote API fetch to this app. Listing 7 shows how to add an API fetch to App.svelte.` ``
`` `Listing 7. Using a REST API (App.svelte)` ``
<script>... async function addRandom(){ const res = await fetch("https://api.quotable.io/random"); const json = await res.json(); quotes = [...quotes, {author:json.author, quote:json.content}]; }</script>...<main>...<button on:click={addRandom}>Add Random Quote</button>...</main>
``` ``Listing 7 adds a button that calls the async `addRandom` function. This function simply calls the [remote quote API](https://github.com/lukePeavey/quotable) and then updates the quotes array with the new quote. Simple!`` ```
`` `This has been a whirlwind tour of some key features of Svelte. There are many more capabilities in the framework, and it is up to the task of building enterprise interfaces right now.` ``
`` `Svelte is also making fast [gains in the marketplace](https://2020.stateofjs.com/en-US/technologies/front-end-frameworks/). It is fourth in usage after the big three (React, Angular, and Vue) but *first* in developer satisfaction and *first* in interest.` ``
`` ` Related: * [JavaScript](https://www.infoworld.com/category/javascript) * [Web Development](https://www.infoworld.com/category/web-development) * [Software Development](https://www.infoworld.com/category/application-development) Matthew Tyson is a founder of [Dark Horse Group, Inc.](http://darkhorse.tech/#home) He believes in people-first technology. When not playing guitar, Matt explores the backcountry and the philosophical hinterlands. He has written for JavaWorld since 2007. Follow * [](https://www.infoworld.com/author/Matthew-Tyson/) * [](https://www.infoworld.com/author/Matthew-Tyson/index.rss) Copyright © 2021 IDG Communications, Inc. * [Stay up to date with InfoWorld’s newsletters for software developers, analysts, database programmers, and data scientists](https://www.infoworld.com/newsletters/signup.html). * [Get expert insights from our member-only Insider articles](https://www.infoworld.com/insider/). ` ``