Svelte中bind绑定的对象为何首次渲染时就被子组件修改?
问题原因
这不是子组件主动修改了定义的obj对象,是Svelte双向绑定的内置响应式机制导致的正常现象:
- 使用
bind:obj语法给子组件传递对象类型props时,Svelte为了实现跨组件响应式同步,不会直接把原始对象传给子组件,而是会给对象包裹一层框架内部使用的响应式代理。控制台日志里看到的带$$开头内部属性的对象就是这个代理,作用是追踪属性读写、触发视图更新,并不会修改对象上的业务属性。 - 首次渲染时
$:标记的响应式语句执行,不是因为obj的业务值被改动,是双向绑定初始化阶段,Svelte要完成代理对象和原始值的关联同步,这个过程会触发一次响应式更新校验,所以日志会被打印。单独打印obj.hello就能看到,值一直是初始定义的'world',没有发生变化。
相关运行日志参考:
验证方法
可以通过几个简单测试确认逻辑:
- 将模板里的
<Comp bind:obj></Comp>改成<Comp {obj}></Comp>,去掉双向绑定只做单向传值,此时Svelte不需要处理子组件回写状态的逻辑,就不会给对象套双向绑定代理,控制台打印的就是最初定义的原始普通对象。 - 不要通过直接打印整个响应式对象的方式判断值是否被修改,Svelte给代理对象加的
$$类内部属性是框架运行时自用的,不会影响业务属性的正常读写,没有主动写赋值逻辑的前提下,业务字段不会被莫名改动。
内容的提问来源于stack exchange,提问作者Fred Hors
相关产品推荐
相关产品推荐

