在 Svelte 中,反应性(reactivity)是一个核心概念,它允许你在数据变化时自动更新 UI。然而,当你在 Svelte 组件中使用类成员时,直接修改类成员的属性不会触发 UI 更新。这是因为 Svelte 的反应性系统依赖于对顶层变量的赋值操作来检测变化。
假设你有一个类 Person
,并在 Svelte 组件中使用它:
<script>
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
}
let person = new Person('Alice', 30);
function updateAge() {
person.age += 1; // 直接修改类成员属性
}
</script>
<p>{person.name} is {person.age} years old.</p>
<button on:click={updateAge}>Increase Age</button>
在这个示例中,点击按钮后,person.age
的值会增加,但 UI 不会更新。这是因为 Svelte 无法检测到 person.age
的变化。
要解决这个问题,你可以使用以下几种方法:
通过重新赋值顶层变量来触发 Svelte 的反应性系统:
<script>
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
}
let person = new Person('Alice', 30);
function updateAge() {
person.age += 1;
person = { ...person }; // 重新赋值顶层变量
}
</script>
<p>{person.name} is {person.age} years old.</p>
<button on:click={updateAge}>Increase Age</button>
在这个示例中,通过重新赋值 person
变量,Svelte 能够检测到变化并更新 UI。
你可以使用 Svelte 的 writable
store 来管理类实例的状态:
<script>
import { writable } from 'svelte/store';
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
}
const personStore = writable(new Person('Alice', 30));
function updateAge() {
personStore.update(person => {
person.age += 1;
return person;
});
}
</script>
<p>{$personStore.name} is {$personStore.age} years old.</p>
<button on:click={updateAge}>Increase Age</button>
在这个示例中,personStore
是一个 Svelte store,通过 update
方法来修改 person
实例的属性。使用 $personStore
可以自动订阅 store 的变化并更新 UI。
你可以使用 JavaScript 的 Proxy
对象来拦截对类成员的修改,并触发 Svelte 的反应性系统:
<script>
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
}
let person = new Person('Alice', 30);
person = new Proxy(person, {
set(target, property, value) {
target[property] = value;
person = { ...target }; // 重新赋值顶层变量
return true;
}
});
function updateAge() {
person.age += 1;
}
</script>
<p>{person.name} is {person.age} years old.</p>
<button on:click={updateAge}>Increase Age</button>
在这个示例中,Proxy
拦截对 person
属性的修改,并通过重新赋值顶层变量来触发 Svelte 的反应性系统。
领取专属 10元无门槛券
手把手带您无忧上云