为何Svelte中通过对象方法修改属性不会触发重新渲染?
现象原因
Svelte的响应式能力是编译期注入实现的,编译组件时只会扫描组件<script>根作用域下的赋值语句,为这些语句自动追加触发视图重渲染的逻辑:
- 组件内定义的add函数中,
numObj.numbers = [...]属于组件根作用域下的赋值操作,Svelte识别到该操作修改了顶层变量numObj的属性,因此自动注入了重渲染逻辑,调用后会更新视图。 - 类N内部的add方法中,
this.numbers = [...]的赋值逻辑定义在类的内部作用域,Svelte默认不会扫描类内部的代码,因此不会为这个赋值追加重渲染逻辑,哪怕值实际发生了变化,Svelte也不会触发视图更新。
不使用store的解决方案
不需要将属性改为store,有两种常用方案可以实现调用对象方法触发重渲染:
方案1:调用方法后追加无意义赋值触发响应式
直接在组件作用域调用对象方法后,补充一句对该对象的自赋值即可,Svelte只要检测到组件根作用域下对响应式变量的赋值操作,就会触发重渲染:
<button on:click={() => { numObj.add(4) numObj = numObj // 触发响应式更新 }}> add number </button>
方案2:改造类定义,内置更新触发逻辑
可以在类初始化时传入一个更新触发函数,类方法修改完属性后主动调用该函数触发更新:
class N { constructor(updateTrigger) { this.numbers = [1,2,3] this.updateTrigger = updateTrigger } add(newN) { this.numbers = [...this.numbers, newN] this.updateTrigger() // 修改完成后主动触发更新 } } // 初始化时传入触发函数 const numObj = new N(() => numObj = numObj)
改造后直接调用numObj.add(4)就可以自动触发重渲染,不需要额外修改调用逻辑。
内容的提问来源于stack exchange,提问作者Corrl
相关产品推荐
相关产品推荐

