[英]How can I export a function from a Svelte component that changes a value in the component?
我有一个名为WastedTime.svelte
的组件,其值为wastedTime
。 还有一个 function 将值更改为50
(在我的实际代码中,这是一个 animation 但这是堆栈溢出的简化测试用例)。
为了允许从父级调用子 function,我在 Svelte 文档中使用了<script context="module">
:
<script context="module">
var wastedTime = 0;
export function changeNumber(){
console.log('changing number')
wastedTime = 50
}
</script>
<script>
// Putting 'var wastedTime = 0' here doesn't work either
</script>
<h1>Wasted time: {wastedTime}</h1>
父级从 onMount 调用子级中的onMount
:
<script>
import { onMount } from 'svelte';
import WastedTime, {changeNumber } from './WastedTime.svelte';
onMount(() => {
changeNumber()
});
</script>
<WastedTime />
问题是,由于在<script context="module">
中引用了wastedTime
,它似乎无法更改wastedTime
。 导出的 function 运行,但wastedTime
保持为 0。
我尝试过: - 将var wastedTime = 0
放入<script context="module">
- 将var wastedTime = 0
放入<script>
两者都不起作用。
如何从更改组件中的值的 Svelte 组件导出 function?
<script context="module">
不是响应式的——更改此块内的变量不会影响单个实例(除非您更改了存储值,并且每个实例都订阅了该存储)。
相反,直接从实例中导出changeNumber
function,并使用bind:this
获取对它的引用:
<script>
var someNumber = 0;
export function changeNumber(){
console.log('changing number')
someNumber = 56
}
</script>
<h1>Wasted time: {someNumber}</h1>
<script>
import { onMount } from 'svelte';
import WastedTime from './WastedTime.svelte';
let wastedTimeComponent;
onMount(() => {
wastedTimeComponent.changeNumber()
});
</script>
<WastedTime bind:this={wastedTimeComponent} />
此处演示: https://svelte.dev/repl/f5304fef5c6e43edb8bf0d25d634f965
丰富的答案的简化版本:
<script>
import Time from './Time.svelte';
let timeComponent;
let time;
</script>
<Time bind:this={timeComponent} bind:time />
<h1>Spent time: {time} ms</h1>
{#if timeComponent}
<button on:click={() => timeComponent.spendTime() }>Click me</button>
{:else}
Loading...
{/if}
<script>
export var time = 0;
export function spendTime() {
time += 50;
}
</script>
这里的关键是export function
。
嗯,这是一个该死的好问题!
我的第一次尝试:
我已经尝试过@Rich Harris 的答案(从组件中导出 function,在使用带有onMount
事件侦听器的组件时绑定它)。 这个概念确实很可靠,但我的问题有点复杂——我试图传递一个带有参数的事件,以便从外部调用。 是的 - 这个参数是使用{#await}
伪造的......所以......这种方法不走运
我的第二次尝试:
在了解了有关 svelte 如何处理事件的更多信息(我是 svelte 的新手并随着我的进步而学习)之后,我发现了这篇很棒的文章。 简而言之:让我们的组件真正面向事件! 在你的问题中 - 你实际上试图实现onload
事件......所以......为什么我们不应该这样做?
组件.svelte
<script>
import { createEventDispatcher, onMount } from 'svelte';
const dispatch = createEventDispatcher();
function doSomething() { console.log('wowza!') }
// wait for onMount to trigger, then dispatch event named "load"
onMount(() => dispatch('load',
{
data: 'yay',
doSomething
}));
</script>
应用程序.svelte
<script>
import { Component } from './component.svelte';
function component_load(event)
{
console.log(event.detail.data);
event.detail.doSomething();
}
</script>
<Component on:load={component_load} />
所以 - 是的,我今天学到了一些东西:另外:
dispatch
可以被触发以响应其他事件——让你为你的组件构建一个完整的生命周期惊人!
父组件:
<script>
import Counter from './Counter.svelte'
let counterElement
</script>
<Counter bind:this={counterElement} />
<button on:click={_=> counterElement.add()}>Add</button>
子组件:
<script>
export const add =_=> count += 1
let count = 0
</script>
<div>Count: {count}</div>
一探究竟:
https://svelte.dev/repl/70cff59aee444dd3ab772a244bd8fa36?version=3.48.0
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.