sveltekit和appwrite云:如何构建列表应用程序
#javascript #教程 #appwrite #svelte

创建可靠且实用的应用程序在现代网络开发中至关重要。开发人员不仅会不断寻求不仅加快开发过程,而且提供更好功能和性能的框架和工具。在这种情况下,AppWrite和Svelte的配对是一个完整的工具包,使程序员能够快速创建功能丰富的Web应用程序。

AppWrite是一种作为服务(BAAS)平台的开源后端,为开发人员提供了许多服务,例如管理用户身份验证,数据存储,文件存储等更多的直觉API,以抽象复杂的后端操作,从而使开发人员可以集中精力关于构建可扩展前端应用程序。

Svelte是一个免费的开源前端组件框架,用于通过在构建时间编译组件来构建用户界面,而无需virtual DOM导致更快的渲染。

在本文中,您将学习如何使用AppWrite的API创建一个列表应用程序,其中具有诸如Task Creation和Deletion之类的功能,并将数据存储在Appwrite Cloud中,以利用AppWrite,Svelte和Tailwind CSS进行样式。

源代码

此项目的完整源代码在此GitHub repo中。

演示

要尝试实时演示,请检查out here

demo app

先决条件

在本教程中,您将需要以下内容:

  • 在您的本地计算机上安装了JavaScript运行时Node.js
  • 基本的JavaScript知识和对Svelte的理解
  • 一个Appwrite云帐户。 Sign-up是免费的

设置appwrite云

使用AppWrite Cloud,您无需使用Docker在系统上运行本地实例。一切都发生在云中。

对于设置,请转到您的AppWrite Cloud Admin Console,并单击+创建项目按钮来创建一个新项目。

create project

创建数据库
“数据库”部分允许您编辑,创建和查看收集。导航到已完成的项目中,单击控制台的左窗格上的数据库选项卡,然后创建一个新的数据库。

create a database

创建集合
创建数据库后,是时候为您的项目添加新集合了。在集合选项卡下,单击+创建集合按钮并给它一个名字。

collections

导航到 collections 以通过添加属性来定义和创建数据结构。

adding attributes

这是您的属性应该是什么样的:

属性键 属性类型 大小 默认值 必需
项目 字符串 255 -

仍然在集合中菜单,在设置下选项卡,更改读取和写入权限,并删除收集的权限。

roles and permissions

向您的项目添加平台

此步骤至关重要,因为它将验证来自客户端的请求到Appwrite Cloud Console。

在“控制台主页”上,单击概述选项卡,然后滚动到“ 集成”部分。单击“添加平台”,然后从下拉列表中选择一个选项。

ps :对于此应用程序,选择 Web应用程序选项。

web app platform

Web
要添加Web平台,请给它一个名称主机名称可以是您想要的任何东西,主机可以是Web项目在开发过程中访问的领域。 主机可以使用星号(*****)符号在本地测试Web应用程序。

add platform

创建一个新的Svelte项目

要创建一个新的Svelte项目,请在命令行界面(CLI)中运行此命令来脚手架。

    npm create svelte@latest list-app

按照以下所述的终端上的说明:

  • 接受y flag的安装
  • 从Svelte应用模板中选择骨架项目
  • 对于用打字稿进行类型检查,请选择 no 。如果否则,您很自在使用TS,请选择
  • 最后一个选项是可选的,如果您决定将其添加到项目

使用以下以下命令开始下一步:

    cd listsApp

    npm install (or pnpm install, etc)

    git init && git add -A && git commit -m "Initial commit" (optional)

    npm run dev

上面的命令执行以下操作:

  • cd:导航到创建的Svelte Project目录
  • 第二个命令使用软件包管理器npm安装所有依赖项
  • git命令命令初始化,阶段并保存当前项目状态的快照,并跟踪您的更改
  • 在port 5173上启动开发服务器以预览应用

安装

AppWrite SDK
启动您的终端并键入以下命令将AppWrite Web SDK安装到您的项目:

    npm install appwrite

tailwind CSS
Tailwind是一个公用事业第一的CSS框架,并在您的标记中直接包装了类。将尾风CSS安装到项目上的最佳方法是使用Tailwind CLI工具。查看Sveltekit框架指南,然后关注this process

创建用户界面

列表应用程序的UI将显示AppWrite Cloud中文档中的所有数据,并可以单击删除项目。

src 目录中创建一个名为 lib 的新文件夹。接下来,创建一个名为ItemList.svelte的新文件。

现在,使用以下代码更新这些组件ItemList.svelte+page.svelte

src/lib/ItemList.svelte

    <script>
      export let list;
    </script>

    <button type="button">
      {list}
    </button>

上面的代码段进行以下操作:

  • script 部分使用用于在组件中声明命名导出的导出语法,该组件公示了可在ItemList组件中访问的变量列表
  • 通过按钮中的变量列表元素

src/routes/+page.svelte

    <script>
      import ItemList from "../lib/ItemList.svelte";
    </script>

    <div
      class="w-4/5 mx-auto max-w-6xl flex flex-col lg:w-6/12 select-none min-h-screen"
    >
      <p class="text-center my-6">Delete an item with a click.</p>
      <img
        src="assets/app-launch.svg"
        alt="Launch rocket"
        class="mx-auto w-3/4 lg:w-2/4"
      />
      <input
        type="text"
        placeholder="enter item"
        class="bg-gray-200 p-4 border-0 text-slate-600 rounded-lg text-center text-xl my-3"
      />
      <ul class="flex p-0 flex-wrap gap-3 mt-4">
        <li
          class="md:text-4xl lg:text-2xl bg-slate-100 p-5 rounded-lg grow text-center shadow hover:bg-orange-200 cursor-pointer"
        >
          <ItemList list={"Watch the superbowl half-time show"} />
        </li>
      </ul>
      <footer class="mt-auto">
        <div class="mt-10 text-center text-gray-500">
          <address>
            Built by
            <span class="text-blue-600">
              <a href="https://twitter.com/terieyenike" target="_">Teri</a>
            </span>
            &copy; 2023
          </address>
          <div>
            <p>
              Fork, clone, and star this
              <a
                href="https://github.com/Terieyenike/appwrite-svelte-list-app"
                target="_"
                rel="noopener noreferrer"
                class="text-blue-600">repo</a
              >
            </p>
          </div>
          <p class="text-sm">Appwrite x Svelte x Tailwind CSS</p>
        </div>
      </footer>
    </div>

在上面的代码段中,发生以下情况:

  • 导入组件,ItemList
  • 在整个标记中,尾风CSS课程美化UI
  • 对于图像,请使用保存在 static 文件夹中资产中的任何选择的图像文件夹
  • 声明 props 值为list中的ItemList组件

在这里您应该看到的:

preview list app

ps:到目前为止,应用程序是静态的。

创建环境变量

环境变量是在程序,操作系统(OS)或运行时环境中访问的程序中设置的动态值。他们将敏感信息远离应用程序代码。

在项目目录的根上创建一个新文件.env,并复制此代码:

.env

    PUBLIC_DATABASE_ID="<DATABASE_ID>"
    PUBLIC_COLLECTION_ID="<COLLECTION_ID>"
    PUBLIC_PROJECT_ID="<PROJECT_ID>"
    PUBLIC_INSTANCE_URL="https://cloud.appwrite.io/v1"

用AppWrite Cloud Admin Console中的实际值替换引号中的所有值。

连接到AppWrite后端

初始化appwrite客户端
让我们在 src 目录中创建一个名为utils.js的文件。复制纸条此代码:

utils.js

    import {
      PUBLIC_DATABASE_ID,
      PUBLIC_COLLECTION_ID,
      PUBLIC_PROJECT_ID,
      PUBLIC_INSTANCE_URL,
    } from "$env/static/public";
    import { Client, Databases, ID, Query } from "appwrite";

    const client = new Client();

    const databases = new Databases(client);

    client.setEndpoint(PUBLIC_INSTANCE_URL).setProject(PUBLIC_PROJECT_ID);

    export const create = (data) =>
      databases.createDocument(
        PUBLIC_DATABASE_ID,
        PUBLIC_COLLECTION_ID,
        ID.unique(),
        data
      );

    export const getList = databases.listDocuments(
      PUBLIC_DATABASE_ID,
      PUBLIC_COLLECTION_ID,
    [Query.orderDesc("$createdAt")]

    );

    export const deleteList = (database_id, collection_id, data) =>
      databases.deleteDocument(database_id, collection_id, data);

上面的代码将允许您的应用程序在开发中运行。但是,当您想将项目代码推向github时,请改用它,然后将.env文件放在.gitignore文件中。

目前,让我们将此方法与代码一起使用:

utils.js

    import { Client, Databases, ID, Query } from "appwrite";

    const client = new Client();

    const databases = new Databases(client);

    client
      .setEndpoint("https://cloud.appwrite.io/v1")
      .setProject("PROJECT_ID");

    export const create = (data) =>
      databases.createDocument(
        "[DATABASE_ID]",
        "[COLLECTION_ID]",
        ID.unique(),
        data
      );

    export const getList = databases.listDocuments(
      "[DATABASE_ID]",
      "[COLLECTION_ID]",
      [Query.orderDesc("$createdAt")]
    );

    export const deleteList = (database_id, collection_id, data) =>
      databases.deleteDocument(database_id, collection_id, data);

上面的代码执行以下操作:

  • 导入AppWrite软件包并初始化Web SDK的新实例
  • 通过客户端带有端点和项目详细信息
  • 创建函数 data 参数,负责创建文档列出客户端上的所有文档数据。此请求会生成唯一的 id
  • 导出 getList 函数,该函数使用列表文档数据库API与数据库ID和Collection ID,并使用查询端点在用户
  • 最后, deletelist 函数用其唯一 id 使用数据参数删除文档

使用AppWrite API创建数据

由于这是一个CRUD应用程序,让我们处理将新项目发送到AppWrite Cloud。在更新+page.svelte页面之前,请在 src 目录中创建另一个名为store.js的文件。

复制纸条此代码:
src/store.js

    import { writable } from "svelte/store";

    export const data = writable({
      name: "",
    });

在Svelte中,可写的功能是一个内置的商店创建者,使您能够创建一个带有 from 的值的写入商店。

现在已经照顾了,更新+page.svelte组件:

src/routes/+page.svelte

    <script>
      import { create } from "../utils";
      import { data } from "../store";
      ...

      function addToList(e) {
        if (!$data.name) {
          return;
        } else if (e.key !== "Enter") {
          return;
        }
        create({
          item: $data.name,
        }).then(
          function (response) {
            window.location.reload();
          },
          function (error) {
            console.log(error);
          }
        );
        $data.name = "";
      }
    </script>

    <div
      class="w-4/5 mx-auto max-w-6xl flex flex-col lg:w-6/12 select-none min-h-screen"
    >
      <p class="text-center my-6">Delete an item with a click.</p>
      <!-- img src element -->
      <input
        type="text"
        placeholder="enter item"
        on:keydown={addToList}
        bind:value={$data.name}
        class="bg-gray-200 p-4 border-0 text-slate-600 rounded-lg text-center text-xl my-3"
      />
      <ul class="flex p-0 flex-wrap gap-3 mt-4">
        <li
          class="md:text-4xl lg:text-2xl bg-slate-100 p-5 rounded-lg grow text-center shadow hover:bg-orange-200 cursor-pointer"
        >
          <ItemList list={"Watch the superbowl half-time show"} />
        </li>
      </ul>
      <!-- Footer element -->
    </div>

此时,上面的代码执行以下操作:

  • 导入create功能以及 store data
  • addToList函数中,如果输入字段中没有值,则什么都不会发生。另外,使用create函数,键 item 读取值$data.name,如果成功,它将保存在AppWrite中。之后,页面立即重新加载。
  • 带有操作键盘的输入元素事件,该事件会在键盘上听Enter键并绑定空值

让我们尝试将项目发送到AppWrite Cloud。转到您的AppWrite控制台,以确认该值已存储。

stored data in the console

显示列表项目

本节显示在客户端上存储在AppWrite中的项目列表。同样,在+page.svelte组件中更新代码。

src/routes/+page.svelte

    <script>
      import { onMount } from "svelte";
      import { getList, create } from "../utils";
      ...

      let lists = [];

      onMount(() => {
        getList.then(
          function (response) {
            lists = response.documents;
          },
          function (error) {
            console.log(error);
          }
        );
      });

      // addToList function

    </script>
    <div
      class="w-4/5 mx-auto max-w-6xl flex flex-col lg:w-6/12 select-none min-h-screen"
    >
      <!-- p, img, input element -->

      <ul class="flex p-0 flex-wrap gap-3 mt-4">
        {#if lists.length == 0}
          <p class="m-auto mt-8">No data in the database</p>
        {:else}
          {#each lists as list (list.$id)}
            <li
              class="md:text-4xl lg:text-2xl bg-slate-100 p-5 rounded-lg grow text-center shadow hover:bg-orange-200 cursor-pointer"
            >
              <ItemList {list} />
            </li>
          {/each}
        {/if}
      </ul>
      <!-- Footer element -->
    </div>

在上面的代码段中,发生以下情况:

  • 导入onMount生命周期函数以及getList函数
  • 用变量列表声明一个空数组
  • 当组件首先渲染并插入DOM
  • 时,onMount函数立即调用
  • 由于这是一项异步任务
  • <ul>元素中,使用#each表达式循环 lists 数组
  • 通过道具,列表 ItemList组件中的

在此gist中查看+page.svelte文件的整个代码:

itemList 组件中,更新文件:

src/lib/ItemList.svelte

    <script>
      import { deleteList } from "../utils";

      ...

      function handleDeleteListItem() {
        deleteList(list.$databaseId, list.$collectionId, list.$id).then(
          function (response) {
            console.log(`${list.item} successfully deleted`);
            window.location.reload();
          },
          function (error) {
            console.log(error);
          }
        );
      }
    </script>

    <button type="button" on:click={handleDeleteListItem}>
      {list.item}
    </button>

在这种情况下,上面的代码执行此操作:

  • 导入deleteList函数
  • handleDeleteListItem函数将从列表数组中删除一个项目
  • 当用reload()方法发生操作时,页面重新加载
  • 在此之前,在按钮元素中,文本不是动态的;替换为通过的道具

包装

使用Svelte和AppWrite的强大组合构建列表应用程序,将最佳的前端开发和后端服务汇集在一起​​。总之,Svelte和AppWrite之间的连接使开发人员能够通过增强的性能和强大的后端功能有效地构建Web应用程序。

今天尝试使用Appwrite Cloud,您将不断回来,就像demonstration list app一样。

资源