如何在svelte中创建反应类



我正在将我的代码库迁移到svelte。我的业务逻辑包含很多类,它们相互依赖。我创建了一个REPL来可视化我的问题:链接。

在本例中,只有将个人的money属性直接更改为html内联函数(左键(,才能在UI中正确更新该属性。当调用类方法(右键(时,类的状态会更新,而UI不会。

我知道这种行为是有意的,应该使用书写表来实现苗条组件之外的反应性。是否有可能通过使用REPL中的类来实现反应性?为了修复REPL,我需要用可写表替换它们的属性吗?如果是,如何?

<div id="app">
{#each teams as team}
<div>
{#each team.people as person}
<li class="person-row">
<div>{person.name}</div>
<div>{person.money}€</div>
<button on:click={() => (person.money += 1)}>Add 1€ </button>
<button on:click={() => person.addMoney(1)}>Add 1€ </button>
</li>
{/each}
</div>
{/each}
</div>
<script>
class Person {
constructor(name, money) {
this.name = name;
this.money = money;
}
addMoney(x) {
this.money += x;
}
}
class Team {
constructor(name, people) {
this.name = name;
this.people = people;
}
}
const p1 = new Person("Person 1", 1000);
const p2 = new Person("Person 2", 2);
const p3 = new Person("Person 3", 60);
const p4 = new Person("Person 4", 15);
const t1 = new Team("Team 1", [p1, p2]);
const t2 = new Team("Team 2", [p3, p4]);
const teams = [t1, t2];
</script>
<style>
.person-row {
display: flex;
flex-direction: row;
}
.person-row * {
width: 100px;
}
</style>

一个可能的解决方法是将属性重新分配给自己,如下所示:

<button on:click={() => { person.addMoney(1); person.money = person.money; }}

或者,如果您希望避免显式重新分配,也可以从addMoney()方法返回money属性

addMoney(x) {
this.money += x;
return this.money;
}

所以按钮可以是

<button on:click={() => { person.money = person.addMoney(1); }}

在调用一个对对象(或数组(进行变异的方法后,添加一个赋值语句:

person.addMoney(1); person = person

这是推荐的方法,允许Svelte只对该人对象内部的更改做出反应。(使用原始数据和直接突变重写应用程序可能比迁移类更适合Svelte(

另一个选择是使用商店。目前,使用$store表示法只适用于顶级。(这有助于自动订阅和取消订阅(
您与团队和人员的设置使您很难使用内置存储创建干净的设置。

但商店合同是灵活而强大的,允许使用其他反应系统,如RxJS、Redux和Vue:

import { readable} from "svelte/store"
import { reactive as vueReactive, watch } from 'vue'
function reactive(obj, options) {
const ref = vueReactive(obj)
return readable(ref, (set) => {
return watch(ref, (prev, next) => {
set(ref)
}, options);
})
}
const teams = reactive([t1, t2]);
{#each $teams as team}

如此REPL 所示

使用这种方法会带来性能损失,因为teams存储在每次addMoney上都会更新,导致Svelte进行更多的无效检查
这是迁移过程中一个有用的中间步骤。

最新更新