svelte/store
模块导出用于创建 可读、可写 和 派生 存储区的函数。
请记住,您不必使用这些函数在组件中享受 响应式 $store
语法。任何正确实现 .subscribe
、取消订阅和(可选).set
的对象都是一个有效的存储区,并且既适用于特殊语法,也适用于 Svelte 的内置 derived
存储区。
这使得几乎任何其他响应式状态处理库都可以包装起来,以便在 Svelte 中使用。阅读更多有关 存储区契约 的信息,以了解正确的实现是什么样的。
writable永久链接
ts
function writable<T>(value?: T | undefined,start?: StartStopNotifier<T> | undefined): Writable<T>;
用于创建存储的功能,该存储的值可以从“外部”组件设置。它作为具有附加set
和update
方法的对象创建。
set
是一个方法,它接受一个参数,该参数是要设置的值。如果存储值尚未等于该值,则存储值将被设置为该参数的值。
update
是一个方法,它接受一个参数,该参数是一个回调。回调将现有存储值作为其参数,并返回要设置为存储的新值。
ts
import {writable } from 'svelte/store';constcount =writable (0);count .subscribe ((value ) => {console .log (value );}); // logs '0'count .set (1); // logs '1'count .update ((n ) =>n + 1); // logs '2'
ts
import {writable } from 'svelte/store';constcount =writable (0);count .subscribe ((value ) => {console .log (value );}); // logs '0'count .set (1); // logs '1'count .update ((n ) =>n + 1); // logs '2'
如果将函数作为第二个参数传递,则当订阅者数量从零变为一(但不是从一变为二等)时,将调用该函数。该函数将被传递一个set
函数,该函数更改存储的值,以及一个update
函数,该函数的工作方式类似于存储上的update
方法,它采用一个回调函数从其旧值计算存储的新值。它必须返回一个stop
函数,该函数在订阅者数量从一变为零时调用。
ts
import {writable } from 'svelte/store';constcount =writable (0, () => {console .log ('got a subscriber');return () =>console .log ('no more subscribers');});count .set (1); // does nothingconstunsubscribe =count .subscribe ((value ) => {console .log (value );}); // logs 'got a subscriber', then '1'unsubscribe (); // logs 'no more subscribers'
ts
import {writable } from 'svelte/store';constcount =writable (0, () => {console .log ('got a subscriber');return () =>console .log ('no more subscribers');});count .set (1); // does nothingconstunsubscribe =count .subscribe ((value ) => {console .log (value );}); // logs 'got a subscriber', then '1'unsubscribe (); // logs 'no more subscribers'
请注意,当writable
被销毁(例如在刷新页面时)时,其值将丢失。但是,您可以编写自己的逻辑,例如将值同步到localStorage
。
readable永久链接
ts
function readable<T>(value?: T | undefined,start?: StartStopNotifier<T> | undefined): Readable<T>;
创建无法从“外部”设置其值的存储,第一个参数是存储的初始值,第二个参数readable
与writable
的第二个参数相同。
ts
import {readable } from 'svelte/store';consttime =readable (newDate (), (set ) => {set (newDate ());constinterval =setInterval (() => {set (newDate ());}, 1000);return () =>clearInterval (interval );});constticktock =readable ('tick', (set ,update ) => {constinterval =setInterval (() => {update ((sound ) => (sound === 'tick' ? 'tock' : 'tick'));}, 1000);return () =>clearInterval (interval );});
derived永久链接
ts
function derived<S extends Stores, T>(stores: S,fn: (values: StoresValues<S>,set: (value: T) => void,update: (fn: Updater<T>) => void) => Unsubscriber | void,initial_value?: T | undefined): Readable<T>;
ts
function derived<S extends Stores, T>(stores: S,fn: (values: StoresValues<S>) => T,initial_value?: T | undefined): Readable<T>;
从一个或多个其他存储中派生存储。当第一个订阅者订阅时,回调最初运行,然后在存储依赖项发生更改时运行。
在最简单的版本中,derived
采用单个存储,并且回调返回派生值。
ts
import {derived } from 'svelte/store';constdoubled =derived (a , ($a ) =>$a * 2);
回调可以通过接受第二个参数set
和可选的第三个参数update
来异步设置值,在适当的时候调用它们中的一个或两个。
在这种情况下,你还可以将第三个参数传递给 derived
— 派生存储的初始值,在首次调用 set
或 update
之前。如果没有指定初始值,则存储的初始值将为 undefined
。
ts
import {derived } from 'svelte/store';constdelayed =derived (a ,($a ,set ) => {setTimeout (() =>set ($a ), 1000);},2000);constdelayedIncrement =derived (a , ($a ,set ,update ) => {set ($a );setTimeout (() =>update ((x ) =>x + 1), 1000);// every time $a produces a value, this produces two// values, $a immediately and then $a + 1 a second later});
如果你从回调函数返回一个函数,则会在以下情况下调用该函数:a) 回调函数再次运行,或 b) 最后一个订阅者取消订阅。
ts
import {derived } from 'svelte/store';consttick =derived (frequency ,($frequency ,set ) => {constinterval =setInterval (() => {set (Date .now ());}, 1000 /$frequency );return () => {clearInterval (interval );};},2000);
在这两种情况下,都可以将参数数组作为第一个参数传递,而不是单个存储。
ts
import {derived } from 'svelte/store';constsummed =derived ([a ,b ], ([$a ,$b ]) =>$a +$b );constdelayed =derived ([a ,b ], ([$a ,$b ],set ) => {setTimeout (() =>set ($a +$b ), 1000);});
readonly永久链接
ts
function readonly<T>(store: Readable<T>): Readable<T>;
这个简单的帮助器函数使存储变为只读。你仍然可以使用这个新的可读存储订阅原始存储的更改。
ts
import {readonly ,writable } from 'svelte/store';constwritableStore =writable (1);constreadableStore =readonly (writableStore );Property 'set' does not exist on type 'Readable<number>'.2339Property 'set' does not exist on type 'Readable<number>'.readableStore .subscribe (console .log );writableStore .set (2); // console: 2readableStore .set (2); // ERROR
get永久链接
ts
function get<T>(store: Readable<T>): T;
通常,你应该通过订阅存储并随着时间的推移使用值来读取存储的值。有时,你可能需要检索未订阅的存储的值。get
允许你这样做。
它的工作原理是创建订阅,读取值,然后取消订阅。因此,不建议在热代码路径中使用它。
ts
import {get } from 'svelte/store';constvalue =get (store );
类型永久链接
Readable永久链接
用于订阅的可读接口。
ts
interface Readable<T> {…}
ts
subscribe(this: void, run: Subscriber<T>, invalidate?: Invalidator<T>): Unsubscriber;
run
订阅回调invalidate
清理回调
订阅值更改。
StartStopNotifier永久链接
启动和停止通知回调。当第一个订阅者订阅时调用此函数。
ts
type StartStopNotifier<T> = (set: (value: T) => void,update: (fn: Updater<T>) => void) => void | (() => void);
Subscriber永久链接
通知值更新的回调。
ts
type Subscriber<T> = (value: T) => void;
Unsubscriber永久链接
取消订阅值更新。
ts
type Unsubscriber = () => void;
Updater永久链接
更新值的回调。
ts
type Updater<T> = (value: T) => T;
Writable永久链接
用于更新和订阅的可写接口。
ts
interface Writable<T> extends Readable<T> {…}
ts
set(this: void, value: T): void;
- 要设置的
value
设置值并通知订阅者。
ts
update(this: void, updater: Updater<T>): void;
updater
回调
使用回调更新值并通知订阅者。