Skip to main content

Svelte 的反应性是由分配触发的。 改变数组或对象的方法本身不会触发更新。

Svelte's reactivity is triggered by assignments. Methods that mutate arrays or objects will not trigger updates by themselves.

在此示例中,单击 "添加一个数字" 按钮将调用 addNumber 函数,该函数将数字附加到数组,但不会触发 sum 的重新计算。

In this example, clicking the "Add a number" button calls the addNumber function, which appends a number to the array but doesn't trigger the recalculation of sum.

解决此问题的一种方法是将 numbers 分配给自身以告诉编译器它已更改:

One way to fix that is to assign numbers to itself to tell the compiler it has changed:

ts
function addNumber() {
numbers.push(numbers.length + 1);
numbers = numbers;
}

你还可以使用 ES6 扩展语法更简洁地编写此代码:

You could also write this more concisely using the ES6 spread syntax:

ts
function addNumber() {
numbers = [...numbers, numbers.length + 1];
}

同样的规则适用于数组方法(例如 popshiftsplice)以及对象方法(例如 Map.setSet.add 等)。

The same rule applies to array methods such as pop, shift, and splice and to object methods such as Map.set, Set.add, etc.

数组和对象属性的赋值 — 例如 obj.foo += 1array[i] = x — 其工作方式与对值本身进行赋值的方式相同。

Assignments to properties of arrays and objects — e.g. obj.foo += 1 or array[i] = x — work the same way as assignments to the values themselves.

ts
function addNumber() {
numbers[numbers.length] = numbers.length + 1;
}

然而,对诸如此类的引用的间接赋值...

However, indirect assignments to references such as this...

ts
const foo = obj.foo;
foo.bar = 'baz';

or

or

ts
function quox(thing) {
thing.foo.bar = 'baz';
}
quox(obj);

...不会触发 obj.foo.bar 上的反应,除非你后续使用 obj = obj

...won't trigger reactivity on obj.foo.bar, unless you follow it up with obj = obj.

一个简单的经验法则: 更新的变量必须直接出现在赋值的左侧。

A simple rule of thumb: the updated variable must directly appear on the left hand side of the assignment.