为什么Svelte中响应式内部对象绑定的checkbox无法正常工作?
问题原因
你代码中复选框异常的核心原因来自Inner.svelte里的响应式赋值逻辑:
$: innerTeam = { ...team, cars: [] }
- Svelte的响应式声明规则确实是仅当右侧依赖的
team变量发生变更时,才会重新执行这条赋值语句,你手动修改innerTeam的属性本身不会触发该语句执行,这部分你的理解没有问题。 - 但当父组件
App.svelte在4秒后给team赋了新的对象引用时,这条响应式语句会执行,生成一个全新的对象直接覆盖现有的innerTeam,你之前对innerTeam做的所有修改(包括复选框勾选修改的full属性、点击按钮添加的cars数据)都会被全部清空重置,就会出现复选框状态自动回弹、看似无法选中的异常效果。 - 额外的触发因素:父组件4秒后传入的新
team对象没有定义full属性,重置后的innerTeam.full值为undefined,绑定到复选框checked属性时会被自动转为布尔值false,进一步加剧了状态异常的表现。
解决方案
根据你的业务需求,可以选择以下两种修改方案:
方案1:team变更时仅同步属性,保留本地修改
如果希望team更新时,只同步team自带的属性,不覆盖本地修改的full和cars数据,修改Inner.svelte的逻辑如下:
<script> export let team = undefined; // 初始化本地独有属性 let innerTeam = { cars: [] }; // 仅当team变化时合并属性,不覆盖已有本地修改 $: if (team) { innerTeam = { ...innerTeam, ...team } } function addCar() { innerTeam.cars = [...innerTeam.cars, {id: "1", brand: "BMW"}] } </script>
方案2:接受team变更时重置本地状态,补充缺失属性
如果业务逻辑确实需要team更新时清空本地修改的cars和full状态,只需修改App.svelte的赋值逻辑,给新的team对象补充full属性即可避免undefined导致的异常:
<script> import {onMount} from "svelte"; import Inner from "./Inner.svelte" let team = { player: {id: "1", name: "John"}, full: false } onMount(() => setTimeout(()=> { // 补充full属性,避免重置后出现undefined值 team = { player: {id: "2", name: "Bob"}, full: false } }, 4000)) </script>
内容的提问来源于stack exchange,提问作者Fred Hors
相关产品推荐
相关产品推荐

