访问位于对象中的svelte可写

问题描述 投票:0回答:1

在 shadcn svelte svelte 5 端口中 选择组件(使用 bitsui select)bind:value 要求状态(字符串),但 Writable 也可以工作,所以 bind:value={$theme 或 $language } 正确获取和设置值。但是我的设置组件与作为道具传递给它的附加设置一起使用,并将存储作为对象的元素之一,并且我很难从对象中正确地进行可写工作。

<script lang="ts" module> interface SelectItem { label: string; labelRu: string; value: string; } export interface Setting { store: Writable<string>; name: string; nameRu: string; values: SelectItem[]; } </script> <script lang="ts"> import * as Select from '$shared/components/ui/select/index.js'; import { theme } from '$shared/stores/theme'; import { language } from '$shared/stores/language'; import { derived, type Writable } from 'svelte/store'; let { additionalSettings = null }: { additionalSettings?: { [key: string]: Setting } | null } = $props(); let clazz = $state(''); export { clazz as class }; let settings: { [key: string]: Setting } = { theme: { store: theme, name: 'Theme', nameRu: 'Тема', values: [ { label: 'Light', labelRu: 'Светлая', value: 'light' }, { label: 'Dark', labelRu: 'Темная', value: 'dark' } ] }, language: { store: language, name: 'Lingo', nameRu: 'Язык', values: [ { label: 'English', labelRu: 'Английский', value: 'en' }, { label: 'Russian', labelRu: 'Русский', value: 'ru' } ] } }; settings = { ...settings, ...(additionalSettings ?? {}) }; const settingLabel = Object.fromEntries( Object.entries(settings).map(([key, setting]) => [ key, derived([setting.store, language], ([$store, $language]) => { const selectedValue = setting.values.find((value) => value.value === $store); return $language === 'ru' ? selectedValue?.labelRu : selectedValue?.label; }) ]) ); </script> <div class="{clazz !== '' ? clazz + ' ' : ''}flex min-w-[240px] flex-col space-y-4 px-2 py-4 text-sm" > {#each Object.entries(settings) as [key, setting]} <div class="flex items-center space-x-2"> <p class="min-w-[48px]">{$language === 'ru' ? setting.nameRu : setting.name}:</p> <Select.Root type="single" name={key} bind:value={$setting.store}> <Select.Trigger> {#await settingLabel[key] then label} {(label ?? $language === 'ru') ? 'Выберите ' + setting.nameRu : 'Select ' + setting.name} {/await} </Select.Trigger> <Select.Content> {#each setting.values as value} <Select.Item value={value.value}> {$language === 'ru' ? value.labelRu : value.label} </Select.Item> {/each} </Select.Content> </Select.Root> </div> {/each} </div>
我是 Svelte 5 反应式功能的新手,所以也许我要求一些简单的修复。对此深表歉意(

svelte sveltekit svelte-component shadcnui svelte-store
1个回答
0
投票
如果存储在组件的根部声明,则只能与

$

 语法一起使用,但这里的情况并非如此,因为存储来自 
#each
 块。

您可以将

#each

 的内容提取到新组件,将存储传递给该组件,然后它将满足那里的必要条件。

但一般来说,我根本不建议在 Svelte 5 中使用存储,除非它是第三方依赖项,但即使如此,您也可以使用

fromStore

 辅助函数将存储转换为状态对象。这在这里也应该是可能的。

一个简化的例子:

<script> import { writable, derived, fromStore } from 'svelte/store'; const value = writable(2); const double = derived(value, v => v * 2); const settings = [ { name: 'Original', store: value }, { name: 'Doubled', store: double }, ]; </script> {#each settings as { name, store }} {@const state = fromStore(store)} <label> {name} {#if 'set' in store} <input type=number bind:value={state.current} /> {:else} {state.current} {/if} </label> <br> {/each} Stores: {$value} * 2 = {$double}

游乐场

© www.soinside.com 2019 - 2024. All rights reserved.