[svelte]stores全局状态容器

本文介绍了Svelte中的store作为全局状态容器的作用,包括响应式更新、集中式状态管理、跨组件共享的特点,以及如何通过writable和readable函数创建store,以及派生属性和自定义store的使用。
摘要由CSDN通过智能技术生成
参考:Stores / Writable stores • Svelte 教程 | Svelte 中文网
 store是什么

在 Svelte 中,store 是一种特殊的对象,用于在组件之间共享状态。可以将 store 视为一个全局的状态容器,所有订阅该 store 的组件都可以读取其值,并在需要时更新其值。store 提供了一种在组件之间传递数据和状态的机制,使得跨组件通信和状态共享变得更加简单和方便。

但store不是普通的JavaScript变量,有自己的特性和使用方式:

  1. 响应式更新: 当 store 的值发生变化时,所有订阅了该 store 的组件都会自动更新,而不需要手动管理状态的变化和重新渲染的逻辑。

  2. 集中式管理: store 提供了一个集中式的状态管理中心,用于管理应用程序的全局状态。这使得状态的管理更加清晰和可控,避免了状态分散和混乱的情况。

  3. 跨组件共享: store 可以在整个应用程序中共享和使用,从而实现跨组件的状态共享。这使得不同组件之间可以方便地共享数据和状态,从而实现更加灵活和可复用的组件设计。

组件之间共享状态,就是多个组件能够访问和修改相同的数据,从而实现数据的共享和同步更新 

为什么要用store

普通的变量在 Svelte 中也可以在组件之间传递,但是它们通常只适用于父子组件之间的通信,或者在单个组件内部的状态管理。如果你想要在多个不相关的组件之间共享状态,并且希望当该状态发生变化时能够自动更新所有相关的组件,那么使用 store 会更加方便和合适。

使用 store 的主要优势在于它提供了一种集中式的状态管理机制,能够更方便地管理应用程序的全局状态。而普通的变量通常只能在其所在的组件中使用,需要通过 props 或事件来传递给其他组件,这样会导致组件之间的耦合度增加,同时也增加了状态管理的复杂度。

使用 store 还能够实现跨组件的状态共享,而普通的变量通常只能在父子组件之间传递,无法跨越组件层级。

创建store方法
writable函数

writable函数可以创建一个可写的store

app.svelte

<script>
	import { count } from './stores.js';
	import Incrementer from './Incrementer.svelte';
	import Decrementer from './Decrementer.svelte';
	import Resetter from './Resetter.svelte';

	let count_value;

	const unsubscribe = count.subscribe(value => {
		count_value = value;
	});
</script>

<h1>The count is {count_value}</h1>

<Incrementer/>
<Decrementer/>
<Resetter/>

Decrementer.svelte

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

	function decrement() {
		count.update(n => n - 1);
	}
</script>

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

Incrementer.svelte

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

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

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

Resetter.svelte

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

	function reset() {
		count.set(0);
	}
</script>

<button on:click={reset}>
	reset
</button>

stores.js

import { writable } from 'svelte/store';

export const count = writable(0);

在上面的例子中,有很多个svelte文件,这时候用props就不太合适,因为有很多组件了,那就可以用stores,用writable函数创建了一个初始值为0的count变量,每一个组件都可以访问到

readable函数

readable 函数用于创建只读的 store,它适用于那些不需要直接修改值,而是只需要订阅和读取的场景。

stores.js

import { readable } from 'svelte/store';

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

	return function stop() {
		clearInterval(interval);
	};
});

App.svelte

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

	const formatter = new Intl.DateTimeFormat('en', {
		hour12: true,
		hour: 'numeric',
		minute: '2-digit',
		second: '2-digit'
	});
</script>

<h1>The time is {formatter.format($time)}</h1>

derived属性 stores派生

在 Svelte 中,derived 是一种特殊的可计算属性,它允许你基于其他状态或 store 的值派生出新的值。derived 可以帮助你管理和计算状态,以确保你的应用程序保持简洁和高效。 你可以使用 derived 来创建一个派生的状态,该状态的值取决于其他状态的值。当任一依赖状态发生变化时,派生状态也会相应地更新。

App.svelte

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

	const formatter = new Intl.DateTimeFormat('en', {
		hour12: true,
		hour: 'numeric',
		minute: '2-digit',
		second: '2-digit'
	});
</script>

<h1>The time is {formatter.format($time)}</h1>

<p>
	This page has been open for
	{$elapsed} {$elapsed === 1 ? 'second' : 'seconds'}
</p>

stores.js

import { readable, derived } from 'svelte/store';

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

	return function stop() {
		clearInterval(interval);
	};
});

const start = new Date();

export const elapsed = derived(
	time,
	$time => Math.round(($time - start) / 1000)
);

 derived可以理解成一个更厉害的更多更多功能的值传递,可以自动更新,可以在里面定义复杂的计算逻辑等等

自定义stores

只要一个对象正确的使用 subscribe ,它就是可以称之为store。因此,使用特定语法来创建自定义 stores变得非常容易

比如在前面的writable例子中,count变量包含了increment、 decrement 和 reset组件,,为了防止暴露set,update方法,可以进行更改

App.svelte

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

<h1>The count is {$count}</h1>

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

stores.js

import { writable } from 'svelte/store';

function createCount() {
	const { subscribe, set, update } = writable(0);

	return {
		subscribe,
		increment: () => update(n => n + 1),
		decrement: () => update(n => n - 1),
		reset: () => set(0)
	};
}

export const count = createCount();
绑定store

如果 store可写入的(即具有set方法),则可以绑定其值,就像可以绑定局部组件状态一样。

App.svelte

<script>
	import { name, greeting } from './stores.js';
</script>

<h1>{$greeting}</h1>
<input bind:value={$name}>

<button on:click="{() => $name += '!'}">
<!--这里的$name += '!' 相当于 name.set($name + '!')-->
	Add exclamation mark!
</button>

stores.js

import { writable, derived } from 'svelte/store';

export const name = writable('world');

export const greeting = derived(
	name,
	$name => `Hello ${$name}!`
);
  • 21
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值