我正在尝试在Sveltejs中创建一个Form组件。
此Form组件将使用<slot />
来让其父级(App.svelte)定义哪些Inputs和Buttons应该在Form内。
Inputs和Buttons也是组件,一旦Input组件的值更改,我想更新父Form组件内的对象,当单击Button时,我想将数据发送回App组件。
我试图阅读Svelte文档并解决<slot let:name={value}>
时遇到的这个问题,但是当Input组件的值更改时,我找不到更新Form组件的方法。
这是我要执行的操作的结构:
App.svelte
...
<Form on:submit={saveReceivedData}>
<Input name="..." value="..." />
<Button />
</Form>
...
Form.svelte
<script>
...
let data = {}
</script>
...
<form>
<slot />
</form>
...
Input.svelte
...
<input name={name} value={value} on:input={updateDataVariableOnFormComponent} />
...
Button.svelte
...
<button on:click={sendDataVariableToAppComponent}>Send</button>
...
如果需要,我可以尝试向您发送完整的代码。但是,由于我的问题不是“我做错了什么?”但是“我该怎么做?”,我更喜欢以抽象的方式写问题。
答案 0 :(得分:2)
当子组件更改时,您可以使用组件绑定来更新父组件中的数据:
syncErrors
有了该绑定,父级中的<Input name="..." bind:value={someValue} />
将同步到子级中的someValue
。
要通知父项有关子项中的事件而不是状态更改,您可以使用event dispatcher ...
value
...在这种情况下,您可以收听<!-- Button.svelte -->
<script>
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher();
</script>
<button on:click={() => dispatch('thinghappened', someData)}>Send</button>
事件...
thinghappened
...或者您可以简单地使用<Button on:thinghappened={e => doSomethingWith(e)}/>
转发DOM事件,并使用<button on:click>Send</button>
监听父事件中的click事件。
答案 1 :(得分:0)
这就是我想要做的。老实说,我对此不是100%满意,但是我爱Svelte:D
App.svelte
<script>
import Form from "./Form.svelte"
import Input from "./Input.svelte"
import Button from "./Button.svelte"
let data = {
name: "John",
surname: "Smith"
}
const saveValues = (event) => {
data = event.detail
}
</script>
<Form data={data} let:saveMe let:updateMe on:save={saveValues}>
<Input
label="Name"
name="name"
value={data.name}
on:input={updateMe}
/>
<Input
label="Surname"
name="surname"
value={data.surname}
on:input={updateMe}
/>
<Button on:click={saveMe}>
Save
</Button>
</Form>
<h4>Saved data</h4>
<ul>
{#each Object.entries(data) as d}
<li>{d[0]}: {d[1]}</li>
{/each}
</ul>
Form.svelte
<script>
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher();
export let data;
const saveMe = () => dispatch('save', data)
const updateMe = (e) => data = {...data, [e.detail.name]: [e.detail.value]}
</script>
<slot saveMe={saveMe} updateMe={updateMe} />
Input.svelte
<script>
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher();
export let name;
export let label = false;
export let value = "";
</script>
<div class="input-field">
<input
id={name}
name={name}
value={value}
on:input={(e) => {
value = e.target.value
dispatch('input', e.target)
}}
/>
{#if label}
<label
for={name}
class:active={value.length > 0}
>{label}</label>
{/if}
<slot />
</div>
Button.svelte
<button on:click>
<slot />
</button>