我正在编码一些项目以学习Svelte,并且我一直在尝试制作类似于电子表格的内容,在电子表格中,用户键入或更改数字,并且使用预先定义的公式来进行微积分(用户无法更改公式)。我已经尝试过了,但是我不能做出反应。
为此,我创建了一个名为Spreadsheet的组件,该组件具有两个道具(数据和列),类似于Quasar为Tables做的事情。
Here是带有示例的REPL。
这个想法是,用户可以更改females, males and area
列上的值,并使用density
公式来被动地更改poblationDensity
列的值。
/* App.svelte */
<script>
import Spreadsheet from "./Spreadsheet.svelte";
const poblationDensity = (females, males, area) => {
return (females + males) / area;
};
let data = [
{
"id": 1,
"animal": "White-mantled colobus",
"females": 13,
"males": 33,
"area": 109
},
{
"id": 2,
"animal": "Woodpecker, red-headed",
"females": 99,
"males": 88,
"area": 252
},
{
"id": 3,
"animal": "White-necked raven",
"females": 34,
"males": 36,
"area": 362
},
{
"id": 4,
"animal": "Baleen whale",
"females": 24,
"males": 67,
"area": 457
},
{
"id": 5,
"animal": "Tiger",
"females": 89,
"males": 20,
"area": 476
},
{
"id": 6,
"animal": "White spoonbill",
"females": 56,
"males": 85,
"area": 358
},
{
"id": 7,
"animal": "Giant anteater",
"females": 83,
"males": 98,
"area": 236
},
{
"id": 8,
"animal": "White-fronted capuchin",
"females": 72,
"males": 44,
"area": 163
},
{
"id": 9,
"animal": "Raccoon, crab-eating",
"females": 78,
"males": 61,
"area": 410
},
{
"id": 10,
"animal": "Turtle, long-necked",
"females": 5,
"males": 77,
"area": 472
}
];
const cols = [
{
name: "id",
label: "#"
},
{
name: "animal",
label: "Animal"
},
{
name: "females",
label: "Females"
},
{
name: "males",
label: "Males"
},
{
name: "area",
label: "Area"
},
{
name: "density",
label: "Density",
computed: {
args: ["females", "males", "area"],
method: poblationDensity
}
}
];
</script>
<main>
<Spreadsheet {data} {cols} />
</main>
/* Spreadsheet.svelte */
<script>
export let data = [];
export let cols = [];
</script>
<style>
.numeric {
width: 70px;
}
</style>
<table>
<tr>
{#each cols as col}
<th>{col.label}</th>
{/each}
</tr>
{#each data as item}
<tr>
{#each cols as col}
<td>
<input type="text" class="{col.name !== 'animal' && 'numeric' }"
value={col.computed ? 0 : item[col.name]}
/>
</td>
{/each}
</tr>
{/each}
</table>
答案 0 :(得分:0)
很好的例子!
因此,第一件事是将您的计算功能poblationDensity
实际连接到显示的内容。我们可以像这样更改您的<input >
字段的值:
value={col.computed ? col.computed.method(item) : item[col.name]}
为了使这项工作有效,我对您的功能做了一些调整:
const poblationDensity = ({ females, males, area }) => {
return (females + males) / area;
};
有了这个,我们得到了正确的显示。现在我们需要获取值。
在Svelte中,获取<input />
值的最常见方法是two-way binding。而且还可以使用对象属性!
在我们的例子中,我们需要绑定到字段的值,所以bind:value={...}
。让我们将其添加到示例中。为此,我们需要为只读(计算)值分离标记:
{#if col.computed}
<input
type="text"
class={col.name !== 'animal' && 'numeric'}
value={col.computed.method(item)} />
{:else}
<input
type="text"
class={col.name !== 'animal' && 'numeric'}
bind:value={item[col.name]} />
{/if}
然后...恩,我们来了!缺少完整! Updated REPL
每次更新值时,bind:value
都会在data
数组中更新它。 Svelte了解此更改,并相应地重新渲染受影响的行。此时,将重新计算计算出的值。
另一种方法是使用一个中间数组来保存计算值。为此,斯维尔特提供了reactive declarations & statements。他们外星人的外观乍一看让他们有点吓人,但是一旦您习惯了它们,它们就会像魔术一样!