벨벳 저장소를 유지하는 방법
벨벳 저장소를 유지하는 방법
페이지를 새로 고친 경우에도 데이터를 사용할 수 있도록 svelte 저장소 데이터를 유지할 수 있는 직접적인 옵션이 옵션이 있습니까.
값이 반응적이기를 원하기 때문에 로컬 스토리지를 사용하지 않습니다.
스토어에 대한 구독을 수동으로 생성하고 localStorage에 대한 변경 사항을 유지할 수 있으며 localStorage의 잠재적 값을 기본값으로 사용할 수도 있습니다.
예
<script>
import { writable } from "svelte/store";
const store = writable(localStorage.getItem("store") || "");
store.subscribe(val => localStorage.setItem("store", val));
</script>
<input bind:value={$store} />
당신은 이것도 확인해 보는 것이 좋을 것이다
또한 sapper를 사용하고 서버에서 무언가를 실행하지 않으려면 onMount 후크를 사용할 수 있습니다
onMount(() => {
console.log('I only run in the browser');
});
출처: 마티아스 스탈:
라고 불리는 스토어 변수가 있다고 가정해보자.
// store.js import { writable } from 'svelte/store'; export const count = writable(0); // App.svelte import { count } from 'store.js';
저장소를 지속적으로 유지하려면 개체에 함수를 포함하면 됩니다.
// store.js import { writable } from 'svelte/store'; const createWritableStore = (key, startValue) => { const { subscribe, set } = writable(startValue); return { subscribe, set, useLocalStorage: () => { const json = localStorage.getItem(key); if (json) { set(JSON.parse(json)); } subscribe(current => { localStorage.setItem(key, JSON.stringify(current)); }); } }; } export const count = createWritableStore('count', 0); // App.svelte import { count } from 'store.js'; count.useLocalStorage();
그런 다음 에서 기능을 호출하여 영구 상태를 활성화합니다.
JHeth는 "매장을 소비하는 부품 안에 또는 안에 배치하라"고 제안했다. "
누군가 자바스크립트 객체로 이것을 작동시켜야 할 경우:
export const stored_object = writable(
localStorage.stored_object? JSON.parse(localStorage.stored_object) : {});
stored_object.subscribe(val => localStorage.setItem("stored_object",JSON.stringify(val)));
이점은 쓰기 가능한 개체에 $속기로 액세스할 수 있다는 것입니다.
<input type="text" bind:value={$stored_object.name}>
<input type="text" bind:value={$stored_object.price}>
TLDR: 설정 및 가져오기뿐만 아니라 삭제도 처리하는 기능이 있습니다.
function persistent(name) {
const value = writable(localStorage.getItem(name));
value.subscribe(val => [null, undefined].includes(val) ? localStorage.removeItem(name) : localStorage.setItem(name, val));
return value;
}
export const my_token = persistent('token');
추론: 직관과 반대로, 다음에 대한 반환을 무효로 설정하지는 않겠지만, 그것은 누군가가 원하는 것이 아닐 가능성이 높다. 따라서 정의되지 않은 null도 확인하고 그에 따라 항목을 삭제합니다.
이 기능은 벨벳 저장소를 localStorage와 동기화합니다. 저장된 값이 없으면 대신 initValue 매개 변수를 사용합니다.
Typescript도 추가했습니다.
import { writable, Writable } from 'svelte/store';
const wStorage = <T>(key: string, initValue: T): Writable<T> => {
const storedValueStr = localStorage.getItem(key);
const storedValue: T = JSON.parse(storedValueStr);
const store = writable(storedValueStr != null ? storedValue : initValue);
store.subscribe((val) => {
localStorage.setItem(key, JSON.stringify(val));
})
return store;
}
export default wStorage;
그런 다음 익숙한 다른 곳에서 이 기능을 사용할 수 있습니다:
const count = wStorage<number>('count', 0);
앱에서 SSR을 사용하고 있으며 쓰기 가능한 모든 방법을 사용하거나 확인하지 않으려는 경우. 다음은 수정된 버전입니다:
const wStorage = <T>(key: string, initValue: T): Writable<T> => {
const store = writable(initValue);
if (typeof Storage === 'undefined') return store;
const storedValueStr = localStorage.getItem(key);
if (storedValueStr != null) store.set(JSON.parse(storedValueStr));
store.subscribe((val) => {
localStorage.setItem(key, JSON.stringify(val));
})
return store;
}
와 ('successor)의 경우 다음을 사용합니다:
<script>
import { onMount } from 'svelte';
import { writable } from "svelte/store";
let value;
onMount(() => {
value = writable(localStorage.getItem("storedValue") || "defaut value");
value.subscribe(val => localStorage.setItem("storedValue", val));
})
</script>
<input bind:value={$value} />
에서 사용할 수 없습니다
Svelte Kit의 경우 SSR에 문제가 있었습니다. 이것은 , 및 를 기반으로 한 나의 솔루션이었다.
추가적으로 이 솔루션은 변경된 경우(예: 다른 탭) 쓰기 가능한 파일도 업데이트합니다. 따라서 이 솔루션은 여러 탭에서 작동합니다. 를 참조하십시오
이것을 타이프스크립트 파일에 넣습니다. 예:
import { browser } from '$app/env';
import type { Writable } from 'svelte/store';
import { writable, get } from 'svelte/store'
const storage = <T>(key: string, initValue: T): Writable<T> => {
const store = writable(initValue);
if (!browser) return store;
const storedValueStr = localStorage.getItem(key);
if (storedValueStr != null) store.set(JSON.parse(storedValueStr));
store.subscribe((val) => {
if ([null, undefined].includes(val)) {
localStorage.removeItem(key)
} else {
localStorage.setItem(key, JSON.stringify(val))
}
})
window.addEventListener('storage', () => {
const storedValueStr = localStorage.getItem(key);
if (storedValueStr == null) return;
const localValue: T = JSON.parse(storedValueStr)
if (localValue !== get(store)) store.set(localValue);
});
return store;
}
export default storage
다음과 같이 사용할 수 있습니다:
import storage from '$lib/store'
interface Auth {
jwt: string
}
export const auth = storage<Auth>("auth", { jwt: "" })
벨벳 버전으로 작동합니다.
src/store.js 파일:
import { writable } from "svelte/store";
import { browser } from "$app/env"
export const fontSize = writable(browser && localStorage.getItem("fontSize") || "15");
fontSize.subscribe((value) => {
if (browser) return localStorage.setItem("fontSize", value)
});
내 프로젝트 중 하나에서 이 코드를 복사했다
import type { Writable, StartStopNotifier, Unsubscriber } from 'svelte/types/runtime/store';
import { writable } from 'svelte/store';
const attach = (writable: Writable<unknown>, key='store'): void =>{
const json = localStorage.getItem(key);
if (json) {
writable.set(JSON.parse(json));
}
writable.subscribe(current => {
localStorage.setItem(key, JSON.stringify(current));
});
}
interface Savable<T> extends Writable<T> {
mount(localstore: Storage): void
dismount(localstore: Storage): JSON
unsub: Unsubscriber
}
function savable<T>(key: string, value?: T, start?: StartStopNotifier<T>): Savable<T>{
const base = writable(value, start)
return {
...base,
mount(localstore) {
if(this.mounted) throw new Error("Already mounted");
this.mounted = true;
const json = localstore.getItem(key);
if (json) {
base.set(JSON.parse(json));
}
this.unsub = base.subscribe(current => {
localStorage.setItem(key, JSON.stringify(current));
});
console.log(this)
},
dismount(localstore) {
if(!this.mounted) throw new Error("Not mounted");
const json = JSON.parse(localstore.getItem(key))
this.unsub()
localstore.removeItem(key)
return json
},
unsub() {
throw new Error('Cannot unsubscribe when not subscribed')
}
}
}
export {
attach,
savable,
};
export type {
Savable
}
export default savable
여기에 저장 가능한 것이 사용되는 예가 있다
<!—- Typescript is not required —->
<script lang=ts>
import savable from `$lib/savable`;
const value = savable(‘input_value’);
import { onMount } from ‘svelte’;
onMount(()=>{
value.mount()
})
</script>
<input bind:value={$value}></input>
이 기능을 구현하는 라이브러리를 찾았습니다. 날 위해 일했어.
README의 예:
// in store.ts or similar
import { writable } from 'svelte-local-storage-store'
// First param `preferences` is the local storage key.
// Second param is the initial value.
export const preferences = writable('preferences', {
theme: 'dark',
pane: '50%',
...
})
// in views
import { get } from 'svelte/store'
import { preferences } from './stores'
preferences.subscribe(...) // subscribe to changes
preferences.update(...) // update value
preferences.set(...) // set value
get(preferences) // read value
$preferences // read value with automatic subscription
다음과 같이 수행할 수 있습니다:
import { writable } from 'svelte/store';
import { browser } from '$app/environment';
// check if the item exists in local storage, if so, return the item, otherwise, return null. (This is to avoid errors on initial reads of the store)
// browser && makes sure the command only works in the client side (browser).
const get_local_storage =
browser && localStorage.getItem('presisted_local_store')
? browser && localStorage.getItem('presisted_local_store')
: null;
// create a writable store
export const presisted_local_store = writable(JSON.parse(get_local_storage));
// create a subscribe method for the store to write back to the local storage (again, on the browser)
presisted_local_store.subscribe((value) => {
browser && localStorage.setItem('presisted_local_store', JSON.stringify(value));
SvelteKit에서 공식적인 방법은 스냅샷이라고 불린다:
https://kit.svelte.dev/message/message