You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blazor应用中如何让组件变量与LocalStorage变量同步?

解决方案

方案1:全局主题事件服务(发布订阅模式)

创建一个全局可注入的主题服务,在主题切换时发布事件,所有需要响应的子组件订阅事件并执行更新逻辑。

  1. 定义主题服务:
public class ThemeService
{
    // 主题切换事件
    public event Action? ThemeChanged;

    // 触发事件的方法
    public void NotifyThemeChanged()
    {
        ThemeChanged?.Invoke();
    }
}
  1. 在Program.cs中注册为单例服务:
builder.Services.AddSingleton<ThemeService>();
  1. 在MainLayout中注入服务,切换主题时触发事件:
@inject ThemeService ThemeService
@inject ILocalStorageService LocalStorage

<button @onclick="ToggleTheme">切换主题</button>

@code {
    private async Task ToggleTheme()
    {
        // 更新LocalStorage中的主题样式值
        var currentDiagramColor = await LocalStorage.GetItemAsync<string>("DiagramColor");
        var newDiagramColor = currentDiagramColor == "#FFFFFF" ? "#000000" : "#FFFFFF";
        var newLabelColor = newDiagramColor == "#FFFFFF" ? "#000000" : "#FFFFFF";
        
        await LocalStorage.SetItemAsync("DiagramColor", newDiagramColor);
        await LocalStorage.SetItemAsync("LabelColor", newLabelColor);

        // 触发主题变更通知
        ThemeService.NotifyThemeChanged();
    }
}
  1. 在包含SfChart的子组件中订阅事件,调用load()方法:
@inject ThemeService ThemeService
@implements IDisposable

<SfChart @ref="chartRef">
    <!-- 图表配置 -->
</SfChart>

@code {
    private SfChart? chartRef;
    @inject ILocalStorageService LocalStorage

    protected override void OnInitialized()
    {
        ThemeService.ThemeChanged += OnThemeUpdated;
    }

    private async void OnThemeUpdated()
    {
        // 读取最新样式值并更新组件
        DiagramColor = await LocalStorage.GetItemAsync<string>("DiagramColor");
        LabelColor = await LocalStorage.GetItemAsync<string>("LabelColor");
        
        // 刷新图表
        await chartRef?.Load();
        StateHasChanged();
    }

    public void Dispose()
    {
        // 取消订阅避免内存泄漏
        ThemeService.ThemeChanged -= OnThemeUpdated;
    }
}

方案2:监听LocalStorage变化

利用LocalStorage的变更事件,直接监听主题相关键的变化,自动触发子组件更新。

  1. 在子组件中监听LocalStorage:
@inject ILocalStorageService LocalStorage
@implements IDisposable

<SfChart @ref="chartRef">
    <!-- 图表配置 -->
</SfChart>

@code {
    private SfChart? chartRef;
    private IDisposable? storageSubscription;

    protected override async Task OnInitializedAsync()
    {
        // 初始化加载样式值
        await LoadThemeValues();

        // 监听指定键的变化
        storageSubscription = LocalStorage.OnChanged.Subscribe(args =>
        {
            if (args.Key is "DiagramColor" or "LabelColor")
            {
                InvokeAsync(async () =>
                {
                    await LoadThemeValues();
                    await chartRef?.Load();
                    StateHasChanged();
                });
            }
        });
    }

    private async Task LoadThemeValues()
    {
        DiagramColor = await LocalStorage.GetItemAsync<string>("DiagramColor");
        LabelColor = await LocalStorage.GetItemAsync<string>("LabelColor");
    }

    public void Dispose()
    {
        storageSubscription?.Dispose();
    }
}

方案3:使用级联参数传递主题状态

通过级联参数将主题状态从MainLayout传递给所有子组件,子组件监听参数变化并执行更新。

  1. 在MainLayout中定义级联参数:
<CascadingValue Value="currentTheme" Name="CurrentTheme">
    @Body
</CascadingValue>

<button @onclick="ToggleTheme">切换主题</button>

@code {
    private ThemeModel currentTheme = new();
    @inject ILocalStorageService LocalStorage

    private class ThemeModel
    {
        public string DiagramColor { get; set; } = "#FFFFFF";
        public string LabelColor { get; set; } = "#000000";
    }

    private async Task ToggleTheme()
    {
        // 更新主题状态
        currentTheme.DiagramColor = currentTheme.DiagramColor == "#FFFFFF" ? "#000000" : "#FFFFFF";
        currentTheme.LabelColor = currentTheme.LabelColor == "#000000" ? "#FFFFFF" : "#000000";

        // 同步到LocalStorage
        await LocalStorage.SetItemAsync("DiagramColor", currentTheme.DiagramColor);
        await LocalStorage.SetItemAsync("LabelColor", currentTheme.LabelColor);

        StateHasChanged();
    }
}
  1. 在子组件中接收级联参数并响应变化:
<SfChart @ref="chartRef">
    <!-- 图表配置 -->
</SfChart>

@code {
    private SfChart? chartRef;

    [CascadingParameter(Name = "CurrentTheme")]
    private ThemeModel? Theme { get; set; }

    protected override async Task OnParametersSetAsync()
    {
        if (Theme != null)
        {
            // 更新组件样式变量
            DiagramColor = Theme.DiagramColor;
            LabelColor = Theme.LabelColor;
            // 刷新图表
            await chartRef?.Load();
        }
    }

    private class ThemeModel
    {
        public string DiagramColor { get; set; } = "#FFFFFF";
        public string LabelColor { get; set; } = "#000000";
    }
}

以上方案均无需给@body加载的子组件添加@ref,通过事件驱动、存储监听或级联参数的方式,实现主题变更的全局通知与组件响应。

内容的提问来源于stack exchange,提问作者Aymen Abdessmad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 18:01:23