当前位置: 首页 > article >正文

【前端】Svelte:Store 状态管理

Svelte 提供了内置的状态管理系统,通过 writablereadablederived 三种类型的 Store,可以轻松地在不同组件之间共享状态。相比其他前端框架中需要借助外部库实现状态管理,Svelte 的 Store 内置且使用简单,尤其适用于需要跨组件共享数据的小型应用。

在本教程中,我们将深入学习 Svelte 的 writablereadablederived 状态管理 API,最后通过 Store 实现组件间的状态共享,构建一个小型应用。

Store 概述

在 Svelte 中,Store 是一种响应式的状态容器,可以将 Store 中的数据绑定到组件,并在数据更新时触发自动渲染。Store 的核心 API 包括三种类型:

  1. writable:可读可写的 Store,最常用。
  2. readable:只读 Store,一般用于定时更新数据或从外部数据源获取数据。
  3. derived:派生 Store,可根据其他 Store 的变化自动更新。

使用 Store 的主要步骤如下:

  1. 创建 Store。
  2. 将 Store 数据绑定到组件。
  3. 在组件中读取或修改 Store 数据。

writable:可读写的 Store

writable 是最基础的 Store,支持直接读写。以下示例展示如何创建和使用一个 writable Store。

创建 writable Store

首先,通过 writable 创建一个 Store:

// src/stores/counter.js
import { writable } from 'svelte/store';

export const counter = writable(0);

在这个文件中,我们创建了一个名为 counter 的 Store,初始值为 0。Store 是响应式的,counter 的值发生变化时,所有引用它的组件会自动更新。

在组件中使用 writable Store

在组件中,我们可以直接导入这个 Store 并绑定到组件变量:

<script>
  import { counter } from './stores/counter';

  // 通过 `$counter` 访问 counter 的值
  function increment() {
    counter.update(n => n + 1);
  }
</script>

<button on:click={increment}>Increment</button>
<p>Counter: {$counter}</p>

在这个例子中:

  • 通过 $counter 可以直接获取 counter 的值并绑定到模板中。
  • 使用 counter.update 方法来更新 Store 的值。update 接收一个函数,函数的参数是当前值。

readable:只读的 Store

readable 是一种只读 Store,适用于数据不需要组件内部更改的情况。它可以在特定的时间间隔内自动更新,比如获取时间戳、从 API 获取数据等。

创建 readable Store

下面是一个定时更新的 readable Store 示例:

// src/stores/time.js
import { readable } from 'svelte/store';

export const time = readable(new Date(), set => {
  const interval = setInterval(() => {
    set(new Date());
  }, 1000);

  // 清除定时器
  return () => clearInterval(interval);
});
  • set 是一个函数,用于更新 readable 的值。
  • 定时器每秒调用 set,更新 Store 为新的日期和时间。

在组件中使用 readable Store

<script>
  import { time } from './stores/time';
</script>

<p>Current time: {$time}</p>

在这里,$time 将随着时间的变化自动更新,无需手动设置。

derived:派生的 Store

derived Store 是根据其他 Store 派生出来的值,当源 Store 发生变化时,派生 Store 也会自动更新。这对于在多个 Store 的基础上计算新值非常有用。

创建 derived Store

以下示例展示了一个根据 counter 计算出双倍值的派生 Store:

// src/stores/double.js
import { derived } from 'svelte/store';
import { counter } from './counter';

export const doubleCounter = derived(counter, $counter => $counter * 2);

在这个例子中:

  • doubleCounter 依赖于 counter,每次 counter 变化时,doubleCounter 都会更新为 counter 的两倍。

在组件中使用 derived Store

<script>
  import { counter } from './stores/counter';
  import { doubleCounter } from './stores/double';

  function increment() {
    counter.update(n => n + 1);
  }
</script>

<button on:click={increment}>Increment</button>
<p>Counter: {$counter}</p>
<p>Double Counter: {$doubleCounter}</p>

在这里,$doubleCounter 会随着 $counter 的变化自动更新。

构建小型应用:多组件共享 Store 数据

为了展示如何通过 Store 实现跨组件的数据共享,我们将构建一个小型的计分器应用。该应用包含以下功能:

  1. 主组件包含增加分数和重置分数的按钮。
  2. 显示组件实时显示当前分数和派生的状态信息。

创建主 Store

创建一个可写的 score Store:

// src/stores/score.js
import { writable } from 'svelte/store';

export const score = writable(0);

创建显示状态的派生 Store

根据分数生成一个派生 Store,显示当前状态:

// src/stores/status.js
import { derived } from 'svelte/store';
import { score } from './score';

export const status = derived(score, $score => {
  if ($score >= 10) return 'High Score';
  if ($score >= 5) return 'Good Score';
  return 'Keep Going';
});

主组件:App.svelte

<script>
  import { score } from './stores/score';
  import ScoreDisplay from './ScoreDisplay.svelte';

  function increaseScore() {
    score.update(n => n + 1);
  }

  function resetScore() {
    score.set(0);
  }
</script>

<button on:click={increaseScore}>Increase Score</button>
<button on:click={resetScore}>Reset Score</button>

<ScoreDisplay />

主组件 App.svelte 包含两个按钮,分别用于增加分数和重置分数,并嵌入了 ScoreDisplay 组件。

显示组件:ScoreDisplay.svelte

<script>
  import { score } from './stores/score';
  import { status } from './stores/status';
</script>

<p>Score: {$score}</p>
<p>Status: {$status}</p>

ScoreDisplay 组件显示了当前分数和状态信息,通过 scorestatus 共享数据。

总结

Svelte 内置的 writablereadablederived Store 简化了状态管理的实现,特别适用于多组件共享数据的小型应用。通过将状态存储在 Store 中,我们可以避免复杂的 props 传递和状态提升问题,使得组件结构更加清晰,且提高了数据共享和维护的便利性。


http://www.kler.cn/a/387339.html

相关文章:

  • scala的练习题
  • go T 泛型
  • 国标GB28181视频平台EasyCVR私有化部署视频平台对接监控录像机NVR时,录像机“资源不足”是什么原因?
  • 【LeetCode】【算法】23. 合并K个升序链表
  • LabVIEW编程基础教学(一)--介绍
  • Ubuntu 20.04安装CUDA 11.0、cuDNN 8.0.5
  • 编程语言之战:AI 之后的 Kotlin 与 Java
  • 【DM系列】DM 集成 JDBC 开发指南
  • 杂谈:业务说的场景金融是什么?
  • k8s集群安装(kubeadm)
  • Android打包流程图
  • 5G网卡network connection: disconnected
  • 小程序开发进阶之路-AI编程助手
  • 配置多公钥在多平台使用Git
  • FOFA使用教程之从零到精通
  • javascript实现国密hash(sm3)算法(支持微信小程序),可分多次计算
  • 【论文复现】MSA+抑郁症模型总结(三)
  • 使用 Flask 和 ONLYOFFICE 实现文档在线编辑功能
  • 浏览器发起 HTTP 请求的典型场景
  • lua入门教程:pairs
  • 力扣 多数元素
  • Debezium系列之:Debezium3版本增量快照和只读增量快照应用的变化
  • javascript五子棋小游戏,基于div+canvas的五子棋小游戏
  • 智慧水库数字孪生系统解决方案
  • HTB:Sightless[WriteUP]
  • Science Robotics 综述揭示演化研究新范式,从机器人复活远古生物!