发布于 2026-01-06 17 阅读
0

开始编写 Svelte 单文件组件所需的一切知识 DEV 的全球展示挑战赛,由 Mux 呈现:展示你的项目!

开始编写 Svelte 单文件组件所需的一切知识

由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!

本文是我关于 Svelte 的三篇系列文章的第二部分。在我看来,无需框架即可构建 JavaScript(UI)框架的理念,是前端开发未来发展最有前景的方向。我很期待继续撰写关于 Svelte 的文章。第一部分讨论了如何使用Svelte 和 Sapper 创建静态网站。第三部分展示了如何将 Tailwind CSS 与 Svelte 和 Sapper 结合使用

版本:
Svelte:3.16.7

介绍

Svelte 是一个现代化的框架,用于创建具有赛博朋克风格的 Web 应用。它无需在客户端加载整个库,所有工作都在编译阶段完成。关于 Svelte 还有很多内容可以介绍,但今天我们只讨论如何使用 Svelte 创建应用。

本文重点介绍如何编写 Svelte 单文件组件。文章将阐述如何:

  1. 构建一个苗条的文件
  2. 组成组件
  3. 继续使用 Svelte

.svelte 单文件组件 (SFC)

Svelte 的 SFC 看起来与 Vue 非常相似,或者换句话说:就像 HTML、JavaScript 和 CSS 一样。不过,它与 Vue 的 SFC 略有不同:

一个 .svelte SFC 以<script>代码块开头。它包含了 SFC 的逻辑。它可以导入子组件,并导出数据属性和特性。

后面跟着一个<style>代码块,其中包含该组件的 CSS 代码。与其他基于组件的框架相比,该框架会自动scoped为该组件应用样式,无需为其添加关键字。

默认情况下,样式作用域仅限于组件。要设置全局样式,请添加关键字:<style global></style>

令人惊讶的是,这部分 HTML 代码并没有被包裹在<template>代码块中。也不需要将所有 HTML 标签都包裹在一个外层标签内。重要的是:这里没有<template>代码块。可以直接将 HTML 代码添加到文件中。

一个 .svelte SFC 的示例如下所示:

<!-- component.svelte -->
<script>
  // nothing to do here. This block can be removed.
</script>

<style>
  h1 {
    font-size: 42px;
  }

  p {
    font-size: 14px;
  }
</style>

<h1>Hello World!</h1>
<p>I am a Demo.</p>
Enter fullscreen mode Exit fullscreen mode

由于没有将 HTML 包裹在标签中,因此它与其他基于组件的框架有几点不同:

  • 网格样式可以通过增加自由度而变得更简单。
  • 除了传递属性之外,无法像class=""给子组件那样添加其他属性。

数据属性

Svelte 的模板语言与 Angular/Vue 类似。与这些框架一样,它也与Handlebars有相似之处。要在模板中使用变量,请将其用花括号括起来:{VARIABLE}

<script>
  const title = "World";
</script>

<style>
  h1 {
    font-size: 42px;
  }

  p {
    font-size: 14px;
  }
</style>

<h1>Hello {title}!</h1>
<p>I am a Demo.</p>
Enter fullscreen mode Exit fullscreen mode

虽然我认为在标记中使用变量添加 HTML 是个坏主意,但可以通过编写以下代码来实现<h1>Hello {@html title}</h1>

变量还可以用于将动态值绑定到 HTML 属性。例如,带有 href 变量的锚链接如下所示:

<a href={href} target="_blank" rel="noopener">
  Open Link
</a>
Enter fullscreen mode Exit fullscreen mode

在使用 HTML 属性变量时,一个常见的错误是给变量加上引号。应该是 `\`href={href}而不是 `\ href="{href}"`。

一个很棒的功能是使用简写属性。当变量名与属性名相同时,只需在花括号中添加属性名即可:

<a {href} target="_blank" rel="noopener">
  Open Link
</a>
Enter fullscreen mode Exit fullscreen mode

简写属性可以减少冗余代码。例如,可以使用{href}`for` href={href}

甚至可以展开一个对象来添加多个属性:

<script>
  const link = {
    href: "some src",
    target: "_blank",
    rel: "noopener"
  }
</script>

<a {...link}>
<!-- will be compiled to: <a href="some src" target="_blank" rel="noopener">-->
  Open Link
</a>
Enter fullscreen mode Exit fullscreen mode

条件渲染

与其他框架相比, Vue 的条件渲染if并非else通过指令实现。在 Vue 中,条件渲染需要这样写: `<div class="vue.js <p v-if="true">" />`。而在 Svelte 中,条件渲染if可以通过添加纯代码块并用花括号括起来来实现。

{#if Math.random() > 0.5}
  <p>I like Svelte.</p>
{:else}
  <p>I don't like Svelte.</p>
{/if}
Enter fullscreen mode Exit fullscreen mode

对于条件渲染,if-else代码块可以用花括号括起来。Else代码块是可选的。` #<body>` 表示代码块的开始,` :<body>` 表示代码块的延续,` <body>` 表示/代码块的结束。

事件处理程序

在 UI 框架出现之前,开发者使用原生 JavaScript 为网站添加逻辑和行为。onclick事件处理程序允许在用户点击 HTML 元素时立即添加回调函数。在 Svelte 中,事件处理程序通过元素指令on:添加到 DOM 元素。可以传递一个函数作为引用,也可以编写一个内联函数。

用于on:在 DOM 元素上添加事件处理程序。

以下是一些示例,帮助您了解事件处理程序:

<script>
  let counter = 1;

  function logout() {
    // ... log user out
  }

  function toggleTooltip() {
    // ... show or hide tooltip
  }
</script>

<button on:click={logout}>
  Logout
</button>

<div on:mouseover={toggleTooltip}>
  Info
</div>

<button on:click="{() => a += 1}">
<!-- you can pass the event as property: -->
<!-- <button on:click|preventDefault="{(e) => /* do something with the event e */}"> -->
  a is {a}.
</button>
Enter fullscreen mode Exit fullscreen mode

接下来我们来谈谈如何组合组件。

组成部件

子组件可以直接导入到<script>代码块中,无需再进行注册。

<script>
  import GridItem from '../components/GridItem.svelte';
</script>
Enter fullscreen mode Exit fullscreen mode

该组件可以像其他 HTML 标签一样添加到模板中。

<GridItem></GridItem>
<!-- or <GridItem /> -->
Enter fullscreen mode Exit fullscreen mode

子组件采用驼峰命名法编写,并在<script>代码块中导入。

组件名称区分大小写。建议使用 PascalCase 命名。这样做的好处是,可以将HeaderFooter等已被占用的标签名称用作 Svelte 组件的名称。这与其他框架不同,在其他框架中,像TheHeaderTheFooter这样的名称是一种变通方案,但也明确指出这些组件在页面模板中只能使用一次。

传递属性

可以使用花括号将属性传递{}给子组件。子组件可以通过导出属性来访问它们。声明数据属性的语法是 `<data-attributes>` [let/const] variable = 'abc';,而访问已传递属性的语法是 `<data-attributes> export let variable;`。

<!-- Parent.svelte -->
<script>
  import Child from '../components/Child.svelte';
</script>

<Child title="World!"></Child>

<!-- Child.svelte -->
<script>
  export let title;
</script>

<h1>Hello {title}</h1>
Enter fullscreen mode Exit fullscreen mode

可以添加一个可选的默认值:

<!-- Child.svelte -->
<script>
  export let title = "my dear friend.";
</script>

<h1>Hello {title}</h1>
Enter fullscreen mode Exit fullscreen mode

使用<Child></Child><Child />用于嵌套组件,而无需使用插槽。

使用插槽

现在,是时候创建一个简单的 Grid 了,它带有 GridItems 插槽,可以使用 `<grid>` 标签添加<slot></slot>。请注意,此 Grid 的实现非常简单,每行仅允许两列。@vaheqelyan实现了一个更复杂的Svelte-Grid版本

<!-- Grid.svelte -->
<style>
  .section {
    display: flex;
    flex: flex-wrap;
  }
</style>

<section>
  <slot></slot>
</section>
Enter fullscreen mode Exit fullscreen mode

要在一个组件中使用多个插槽,请添加属性name=以创建命名插槽。命名插槽和未命名插槽可以组合使用。

<!-- GridItem.svelte -->
<style>
  .div {
    width: 50%;
  }
</style>

<div>
  <slot name="title"></slot>
  <hr>
  <slot name="content"></slot>
  <slot></slot>
  <!-- or <slot /> -->
</div>
Enter fullscreen mode Exit fullscreen mode

这是一种创建复杂组件组合的强大方法。下面我们将看到一个完整的网格布局示例:

<!-- index.svelte -->
<script>
  import Grid from '../components/Grid.svelte';
  import GridItem from '../components/GridItem.svelte';

  let title = 'World!";
</script>

<h1>Hello {title}</h1>

<Grid>
  <GridItem>
    <h2 slot="title">I will be rendered within the named slot title.</h2>
    <p slot="content">I will be rendered within the named slot.</h2>
    <p>I will be rendered within the unnamed slot.</p>
  </GridItem>
  <GridItem>
    <h2 slot="title">I only have a headline, nothing else.</h2>
  </GridItem>
</Grid>
Enter fullscreen mode Exit fullscreen mode

在 Svelte 中添加组件、数据、属性等,只需在<script>代码块中导入或声明即可,无需进一步注册。

下一步

🤩 掌握了这些知识,就可以开始实现你的第一个 Svelte 单文件组件了🤩

小型静态页面通常不需要太多功能。为了巩固相关知识,我建议花 1 小时时间学习一下官方教程

还有更多东西需要学习。Svelte 提供了生命周期钩子绑定存储过渡等诸多功能,可以用来创建更复杂的应用程序。继续学习吧!👨‍🎓👩‍🎓

文章来源:https://dev.to/vannsl/all-you-need-to-know-to-start-writing-svelte-single-file-components-cbd