Svelte:当组件更改数据时存储数据不响应,反之亦然

Svelte: Store Data Not Being Reactive When Component Changes Data and Vice Versa

我确定这是一个超级简单的修复,但我在设置可写存储时遇到了一个问题,它主要是反应性的,除非组件更改数据时,App 文件中的反应性不会'火,反之亦然。这是代码:

App.svelte:

<script>
    import { data } from './store.js'
    import Component from './Component.svelte'
    let localData
    data.subscribe((value) => {
        localData = value;
    });
</script>

<h2>In App.svelte</h2>

<p>Hello {localData.name}!</p>

<input name="name" type="text" bind:value={localData.name}>

<p>
    {localData.details.number}
</p>

<h2>In Component.svelte</h2>

<Component />

Component.svelte:

<script>
    import { data } from './store.js'
    let localData
    data.subscribe((value) => {
        localData = value;
    });
</script>

<input type="number" bind:value={localData.details.number}>

<p>Hello {localData.name}!</p>
<p>{localData.details.number}</p>

store.js:

import { writable } from 'svelte/store'

export let data = writable({
    name: 'Bob Smith',
    details: {
            dob: '1982/03/12',
            favoriteFoods: ['apples', 'pears', 'bourbon'],
            number: 1
        },
})

而且,如果您想在 Svelte REP 中使用它:https://svelte.dev/repl/164227336d6c4cc29f7ea0a15e89c584?version=3.44.3

您正在订阅数据并将其放入局部变量,然后绑定到该变量。这意味着商店不知道任何更改并且不会传播更新。两个选项:

第一个选项:摆脱双向绑定并像这样显式更新商店:

<script>
    import { data } from './store.js'
    import Component from './Component.svelte'
    let localData
    data.subscribe((value) => {
        localData = value;
    });

    function updateName(evt) {
        const newName = evt.target.value;
        data.update(value => ({...value, name: newName }));
    }
</script>

<h2>In App.svelte</h2>

<p>Hello {localData.name}!</p>

<input name="name" type="text" value={localData.name} on:input={updateName}>

<p>
    {localData.details.number}
</p>

<h2>In Component.svelte</h2>

<Component />

这非常明确,但也有点样板化。我们有 Svelte 方便的自动订阅功能,所以让我们改用它。第二个也是首选选项:

<script>
    import { data } from './store.js'
    import Component from './Component.svelte'
</script>

<h2>In App.svelte</h2>

<p>Hello {$data.name}!</p>

<input name="name" type="text" bind:value={$data.name}>

<p>
    {$data.details.number}
</p>

<h2>In Component.svelte</h2>

<Component />

注意我们是如何摆脱所有订阅样板的。 $data 访问存储的当前状态,因为它是一个可写存储,您也可以用这种方式写回它。您可以在文档中阅读有关商店的更多信息:https://svelte.dev/docs#component-format-script-4-prefix-stores-with-$-to-access-their-values