在Svelte中是否有一种方法可以在localStorage值更改时始终执行函数?

huangapple go评论82阅读模式
英文:

Is there anyway to always execute a function whenever localStorage value change in Svelte?

问题

我在我的Laravel Inertia Svelte应用程序中使用了一个购买的模板。 这个模板有两种 "形状",垂直(侧边栏菜单)和水平(导航栏菜单)。

我的应用程序现在有3个组件:侧边栏、导航栏和页脚。 它们包含在布局中。 布局看起来像这样:

<main class="main" id="top">
    <TheSidebar />
    <div class="content">
        <slot />
        <TheFooter />
    </div>
</main>
<ThemeCustomizer />

我想做的事情基本上是在localStorage中的值更改时更改布局。 我在ThemeCustomizer组件中有一个按钮,可以更改localStorage的值。 例如,如果我点击垂直按钮,然后localStorage中的值更改为 'vertical',如果我点击水平按钮,它将更改为 'horizontal'。

我尝试了以下操作:

{#if localStorage.getItem('phoenixTheme') === 'vertical'}
    <main class="main" id="top">
        <TheSidebar />
        <div class="content">
            <slot />
            <TheFooter />
        </div>
    </main>
{:else}
    <main class="main" id="top">
        <TheNavbar />
        <div class="content">
            <slot />
            <TheFooter />
        </div>
    </main>
{/if}
<ThemeCustomizer />

但是它不起作用。 当我重新加载页面时,它确实起作用,但是当我只是点击按钮并更改localStorage中的值时,它不起作用。 我猜这是因为if else检查只执行一次。

是否有一种方法可以在localStorage值更改时始终触发if else函数? 谢谢。

英文:

I'm using a bought template in my Laravel Inertia Svelte app. This template has 2 "shapes", Vertical (Sidebar Menus) and Horizontal (Navbar Menus).

My app right now has 3 components: Sidebar, Navbar, and Footer. They are included inside the layout. The layout looks something like this:

&lt;main class=&quot;main&quot; id=&quot;top&quot;&gt;
    &lt;TheSidebar /&gt;
    &lt;div class=&quot;content&quot;&gt;
        &lt;slot /&gt;
        &lt;TheFooter /&gt;
    &lt;/div&gt;
&lt;/main&gt;
&lt;ThemeCustomizer /&gt;

What I want to do is basically change the layout when the value inside localStorage change. I have a button inside ThemeCustomizer component that change the localStorage value. For example, if I click Vertical button, then the value inside localStorage changes to 'vertical', and it changes to 'horizontal' if I click Horizontal button.

I tried to do the following:

{#if localStorage.getItem(&#39;phoenixTheme&#39;) === &#39;vertical&#39;}
    &lt;main class=&quot;main&quot; id=&quot;top&quot;&gt;
        &lt;TheSidebar /&gt;
        &lt;div class=&quot;content&quot;&gt;
            &lt;slot /&gt;
            &lt;TheFooter /&gt;
        &lt;/div&gt;
    &lt;/main&gt;
{:else}
    &lt;main class=&quot;main&quot; id=&quot;top&quot;&gt;
        &lt;TheNavbar /&gt;
        &lt;div class=&quot;content&quot;&gt;
            &lt;slot /&gt;
            &lt;TheFooter /&gt;
        &lt;/div&gt;
    &lt;/main&gt;
{/if}
&lt;ThemeCustomizer /&gt;

However it doesn't work. It does work when I fully reload the page, but it doesn't work when I just click the button and change the value inside localStorage. I assume this is because the if else checking is just done once.

Is there a way to basically always trigger the if else function when the localStorage value change? Thank you.

答案1

得分: 1

你可以将存储包装在一个store中,并订阅storage事件,在更改时更新存储值。然后,如果在标记中通过$store使用存储,它将自动更新。

在这方面可能有完整的实现,也有一些关于在与Svelte存储一起使用本地/会话存储时的问题。

(如果您不需要在多个选项卡之间进行更新,就不需要监听该事件。只要通过所述存储进行所有访问,存储的反应性就足够了。)

英文:

You can wrap the storage in a store and subscribe to the storage event and update the store value on change. If you then use the store via $store in the markup it will update automatically.

There are probably full implementations of this around and there are several questions about local/session storage when used with Svelte stores.

(If you do not need updates across multiple tabs, you do not need to listen for the event. Having the store reactivity will be enough if all access is through said store.)

huangapple
  • 本文由 发表于 2023年6月13日 16:56:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/76463241.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定