svelte/store

svelte/store 模块导出的函数是用于创建 stores

writable

  1. store = writable(value: any)
  1. store = writable(value: any, (set: (value: any) => void) => () => void)

writable 函数创建的store,其值可以被外部组件设置。函数会生成一个带有setupdate函数的对象。

set 函数需要一个参数,即将要赋值的值。如果 store 的值不等于传入的值,那store的值会设置成该值。

update 函数需要一个回调函数作为参数。回调函数以当前 store 的值作为参数,且函数的返回值会赋值给 store。

  1. import { writable } from 'svelte/store';
  2. const count = writable(0);
  3. count.subscribe(value => {
  4. console.log(value);
  5. }); // logs '0'
  6. count.set(1); // logs '1'
  7. count.update(n => n + 1); // logs '2'

如果 writable 函数传入了第二个参数,当订阅者数量从0变化到1的时候(而不是从1到2,或其他),它会被调用。这个函数会传递一个修改 store 的 set 函数作为参数。且必须返回一个终止函数,它会在订阅者的数量从1变到0的时候被调用。

  1. import { writable } from 'svelte/store';
  2. const count = writable(0, () => {
  3. console.log('got a subscriber');
  4. return () => console.log('no more subscribers');
  5. });
  6. count.set(1); // does nothing
  7. const unsubscribe = count.subscribe(value => {
  8. console.log(value);
  9. }); // logs 'got a subscriber', then '1'
  10. unsubscribe(); // logs 'no more subscribers'

readable

  1. store = readable(value: any, (set: (value: any) => void) => () => void)

通过 readable 创建的store, 其值不可从外部进行设置。第一个参数就是store的初始值。

readable 的第二个参数和 writable 的第二个参数一样,除了这个参数对于 writable 是必须参数以外(否则将无法更新 store 的值)。

  1. import { readable } from 'svelte/store';
  2. const time = readable(new Date(), set => {
  3. const interval = setInterval(() => {
  4. set(new Date());
  5. }, 1000);
  6. return () => clearInterval(interval);
  7. });

derived

  1. store = derived(a, callback: (a: any) => any)
  1. store = derived(a, callback: (a: any, set: (value: any) => void) => void | () => void, initial_value: any)
  1. store = derived([a, ...b], callback: ([a: any, ...b: any[]]) => any)
  1. store = derived([a, ...b], callback: ([a: any, ...b: any[]], set: (value: any) => void) => void | () => void, initial_value: any)

derived 的 store 可以是从一个或多个 store 中派生。只要这些依赖项发生改变,回调函数就会执行。

最简单的版本,derived 仅传入单个store,且回调函数返回一个 derived 的值。

  1. import { derived } from 'svelte/store';
  2. const doubled = derived(a, $a => $a * 2);

回调函数可以通过接收第二个参数(set)异步的方式设值,set 函数会在适当的时候调用。

在这个例子中,你还可以传入第三个参数给 derived - 在 set 函数调用之前 store 的初始值 。

  1. import { derived } from 'svelte/store';
  2. const delayed = derived(a, ($a, set) => {
  3. setTimeout(() => set($a), 1000);
  4. }, 'one moment...');

如果回调函数返回的是一个函数,它将在a)回调再次运行时调用,或者b)最后一个订阅者取消订阅时调用。

  1. import { derived } from 'svelte/store';
  2. const tick = derived(frequency, ($frequency, set) => {
  3. const interval = setInterval(() => {
  4. set(Date.now());
  5. }, 1000 / $frequency);
  6. return () => {
  7. clearInterval(interval);
  8. };
  9. }, 'one moment...');

在这两种情况下,参数数组都可以作为第一个参数而不是单个 store 传递。

  1. import { derived } from 'svelte/store';
  2. const summed = derived([a, b], ([$a, $b]) => $a + $b);
  3. const delayed = derived([a, b], ([$a, $b], set) => {
  4. setTimeout(() => set($a + $b), 1000);
  5. });

get

  1. value: any = get(store)

一般情况下,你应该通过订阅来读取 store 的值,使用的是随时间变化的值。有时,你可能需要查看你未订阅的 store 的值, get 就支持这样做。

  1. import { get } from 'svelte/store';
  2. const value = get(store);