怎样在 Svelte 中自定义 store

正文

我们拿一个计数器举例,count 变量存在 store 中,我们用 count.set() 重置,用 count.subscribe() 订阅,用 count.update() 更新,一切看起来都很 OK,但实际上,如果想要更好的可维护性,这个 count 应该继续定义它的行为逻辑,也就是预定义好它的更新是怎样的、它的重置是怎样的。这样看起来似乎是在限制 count 的自由,但这种限制也意味着变动规则是可以把握的,而不是随处都有可能变动,也不是想怎么变就怎么变。

下面是一个没有使用自定义 store 的计数器功能:

// store.js
import { writable } from 'svelte/store'

export const count = writable(0)
<!-- App.svelte -->
<script>
  import { count } from "./store.js";

  const increment = () => count.update((val) => val + 1);
  const decrement = () => count.update((val) => val - 1);
  const reset = () => count.set(0);
</script>


<h1>{$count}</h1>

<button on:click={increment}> + </button>
<button on:click={decrement}> - </button>
<button on:click={reset}> reset </button>

功能逻辑放在特定组件里面,如果其他组件要用,那还得继续写。这其实就很冗余了,而且这些增加、减少、重置的逻辑应该是通用的,就算不通用,判断逻辑也应该写在一起,而不是分散在不同的组件里面。下面是使用自定义 store 后的效果。

// store.js
import { writable } from 'svelte/store'

export const count = createCount(0)

function createCount(defaultVal) {
  const { subscribe, set, update } = writable(defaultVal)
  return {
    subscribe, // 形成 store 的必要条件
    increment() {
      update(val => val + 1)
    },
    decrement() {
      update(val => val - 1)
    },
    reset() {
      set(0)
    },
  }
}
<!-- App.svelte -->
<script>
  import { count } from "./store.js";
</script>


<h1>{$count}</h1>

<button on:click={count.increment}> + </button>
<button on:click={count.decrement}> - </button>
<button on:click={count.reset}> reset </button>

这样做了后,逻辑就被安放到了 store 中,且没有暴露 set 和 update 给外界,意味着这两个方法是被保护起来了,因此增加、减少、重置的逻辑就这样统一做了定义。

注意

只要一个对象正确的使用 subscribe ,它就是可以称之为 store,因此上面自定义 store 中总是需要抛出 subscribe 方法。

参考

https://www.sveltejs.cn/tutorial/custom-stores

原文地址:https://www.cnblogs.com/aisowe/p/15245591.html