Svelte中选择AutoComplete值后InputChip组件不更新的问题
解决Skeleton UI InputChip在AutoComplete选择后不更新的问题
问题分析
你遇到的核心问题是:AutoComplete选择分类后,selectedCategoryChips数组已更新,但InputChip组件的UI未同步。这是因为状态冗余导致的响应式冲突——你通过$: selectedCategoryChips = selectedCategoryLabels同步状态,但InputChip的bind:value会直接修改selectedCategoryChips的引用,打乱了原有同步逻辑,最终导致UI未触发更新。
解决方案
简化状态管理,直接维护InputChip绑定的数组变量,同时确保selectedCategoryIds与芯片标签数组的一致性:
<script lang="ts"> import { page } from "$app/stores"; import { createQuery } from "@tanstack/svelte-query"; import LoadingSpinner from "$lib/components/ui/LoadingSpinner.svelte"; import { toastStore, InputChip, Autocomplete, type AutocompleteOption } from "@skeletonlabs/skeleton"; const { supabase } = $page.data; export let selectedCategoryIds: string[] = []; export let subcatPaths: string[] = []; let whitelist: string[] = []; let selectedCategoryChips: string[] = []; let categoryOptions: AutocompleteOption[] = []; let inputChipCategory: string; $: categories = createQuery({ queryKey: ["categories"], queryFn: async () => { const { data: cats, error } = await supabase.from("categories").select(); if (error) throw error; return cats.map( (category) => ({ label: category.label, value: category.id, keywords: category.keywords } as AutocompleteOption) ); }, onSuccess: (data) => { categoryOptions = data; whitelist = data.map((category) => category.label); // 初始化:根据已选ID匹配对应标签 selectedCategoryChips = data .filter(cat => selectedCategoryIds.includes(cat.value as string)) .map(cat => cat.label); }, onError: (err) => { console.log(err); toastStore.trigger({ message: "Error fetching categories.", background: "variant-filled-error" }); } }); function onCategorySelect(event: CustomEvent<AutocompleteOption>) { const selectedValue = event.detail.value as string; const selectedLabel = event.detail.label as string; if (!selectedCategoryIds.includes(selectedValue)) { // 更新ID数组(保持响应式:重新创建数组) selectedCategoryIds = [...selectedCategoryIds, selectedValue]; // 直接更新芯片标签数组,触发InputChip更新 selectedCategoryChips = [...selectedCategoryChips, selectedLabel]; // 清空输入框,提升体验 inputChipCategory = ''; } } // 监听芯片变化,同步更新ID数组(处理用户手动删除芯片的场景) $: if (categoryOptions.length > 0) { selectedCategoryIds = selectedCategoryChips .map(label => categoryOptions.find(opt => opt.label === label)?.value as string) .filter(id => id); } </script> <div class="label"> <span>Categories</span> <InputChip {whitelist} allowUpperCase bind:input={inputChipCategory} bind:value={selectedCategoryChips} name="chips" placeholder="Enter 3 categories..." chips="variant-filled-primary" min="3" /> </div> <div class="card w-full max-h-48 {$categories.isLoading ? 'p-4' : 'p-1'} overflow-y-auto" > {#if $categories.isLoading} <center> <LoadingSpinner /> </center> {:else if $categories.isSuccess} <Autocomplete options={categoryOptions} denylist={selectedCategoryIds} bind:input={inputChipCategory} on:selection={onCategorySelect} /> {/if} </div>
修改要点
- 移除冗余状态:删除
selectedCategoryLabels变量,直接操作selectedCategoryChips(即InputChip绑定的数组),避免状态同步冲突。 - 直接触发响应式:在选择分类时,通过展开运算符重新创建数组,确保Svelte检测到状态变化并更新UI。
- 双向同步状态:添加响应式监听,当用户手动删除芯片时,自动同步更新
selectedCategoryIds,保证两个数组的一致性。 - 初始化匹配:在分类数据加载完成后,根据初始的
selectedCategoryIds自动生成对应的芯片标签。
内容的提问来源于stack exchange,提问作者Alexander Hunter
相关产品推荐
相关产品推荐

