将 Svelte 应用组件化

在上一篇文章中,我们开始开发待办事项应用程序。本文的主要目标是了解如何将应用程序分解成可管理的组件,以及如何在组件之间共享信息。我们将对应用程序进行组件化,然后添加更多功能,允许用户更新现有的组件。

先决条件

至少,建议您熟悉核心HTMLCSSJavaScript语言,并了解终端/命令行

您需要一个安装了 Node 和 npm 的终端来编译和构建您的应用程序。

目标 学习如何将我们的应用程序分解成组件,以及如何在组件之间共享信息。

与我们一起编写代码

Git

使用以下命令克隆 GitHub 仓库(如果您尚未克隆):

bash
git clone https://github.com/opensas/mdn-svelte-tutorial.git

然后,要进入当前应用程序状态,请运行:

bash
cd mdn-svelte-tutorial/04-componentizing-our-app

或者直接下载文件夹的内容

bash
npx degit opensas/mdn-svelte-tutorial/04-componentizing-our-app

请记住运行npm install && npm run dev以开发模式启动应用程序。

REPL

要使用 REPL 与我们一起编写代码,请从以下地址开始:

https://svelte.net.cn/repl/99b9eb228b404a2f8c8959b22c0a40d3?version=3.23.2

将应用分解成组件

在 Svelte 中,应用程序由一个或多个组件组成。组件是一个可重用、自包含的代码块,封装了属于一起的 HTML、CSS 和 JavaScript,并写入 .svelte 文件中。组件可以很大或很小,但通常定义明确:最有效的组件服务于单一、明确的目的。

定义组件的好处类似于将代码组织成可管理片段的更通用的最佳实践。它将帮助您了解它们之间的关系,促进重用,并使您的代码更易于推理、维护和扩展。

但是,您如何知道哪些内容应该拆分成自己的组件呢?

对此没有硬性规定。有些人更喜欢直观的方法,开始查看标记并围绕每个似乎具有自身逻辑的组件和子组件绘制框。

其他人则应用与决定是否应创建新函数或对象相同的技术。其中一项技术是单一职责原则——即,组件理想情况下只应执行一项操作。如果它最终变得越来越大,则应将其拆分为更小的子组件。

这两种方法应该相互补充,帮助您决定如何更好地组织组件。

最终,我们将把我们的应用程序拆分为以下组件:

  • Alert.svelte:用于传达已发生操作的通用通知框。
  • NewTodo.svelte:允许您输入新待办事项的文本输入框和按钮。
  • FilterButton.svelte全部活动已完成按钮,允许您将过滤器应用于显示的待办事项。
  • TodosStatus.svelte:显示“x 个项目已完成,共 y 个项目”的标题。
  • Todo.svelte:单个待办事项。每个可见的待办事项都将在此组件的单独副本中显示。
  • MoreActions.svelte:UI 底部的选中全部移除已完成按钮,允许您对待办事项执行批量操作。

graphical representation of the list of components in our app

在本文中,我们将专注于创建FilterButtonTodo组件;我们将在以后的文章中介绍其他组件。

让我们开始吧。

注意:在创建我们的前几个组件的过程中,我们还将学习在组件之间通信的不同技术以及每种技术的优缺点。

提取我们的筛选组件

我们将从创建FilterButton.svelte开始。

  1. 首先,创建一个新文件,components/FilterButton.svelte
  2. 在此文件中,我们将声明一个filter prop,然后将相关的标记从Todos.svelte复制到其中。将以下内容添加到文件中:
    svelte
    <script>
      export let filter = 'all'
    </script>
    
    <div class="filters btn-group stack-exception">
      <button class="btn toggle-btn" class:btn__primary={filter === 'all'} aria-pressed={filter === 'all'} on:click={() => filter = 'all'} >
        <span class="visually-hidden">Show</span>
        <span>All</span>
        <span class="visually-hidden">tasks</span>
      </button>
      <button class="btn toggle-btn" class:btn__primary={filter === 'active'} aria-pressed={filter === 'active'} on:click={() => filter = 'active'} >
        <span class="visually-hidden">Show</span>
        <span>Active</span>
        <span class="visually-hidden">tasks</span>
      </button>
      <button class="btn toggle-btn" class:btn__primary={filter === 'completed'} aria-pressed={filter === 'completed'} on:click={() => filter = 'completed'} >
        <span class="visually-hidden">Show</span>
        <span>Completed</span>
        <span class="visually-hidden">tasks</span>
      </button>
    </div>
    
  3. 回到我们的Todos.svelte组件中,我们希望使用FilterButton组件。首先,我们需要导入它。在Todos.svelte