我有一个名为WastedTime.svelte
的组件,其值为wastedTime
。还有一个将值更改为50
的函数(在我的真实代码中,这会生成动画,但这是Stack Overflow的简化测试用例)。
为了允许从父级调用子级功能,我在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
调用子级中的函数:
<script>
import { onMount } from 'svelte';
import WastedTime, {changeNumber } from './WastedTime.svelte';
onMount(() => {
changeNumber()
});
</script>
<WastedTime />
问题在于,由于wastedTime
是在<script context="module">
中引用的,因此似乎无法更改wastedTime
。导出的函数运行,但是wastedTime
保持为0。
我尝试过:
-将var wastedTime = 0
放入<script context="module">
-将var wastedTime = 0
放入<script>
都不行。
如何从Svelte组件导出一个函数以更改该组件中的值?
答案 0 :(得分:4)
<script context="module">
不具有响应性-对此块中的变量所做的更改不会影响单个实例(除非您正在更改商店值,并且每个实例都已订阅该商店)。
相反,直接从实例中导出changeNumber
函数,并使用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?version=3.12.1
答案 1 :(得分:1)
嗯,这是一个该死的好问题!
我的第一次尝试:
我已经尝试了@Rich Harris答案(从组件内部导出函数,将组件与onMount
事件侦听器一起使用时将其绑定)。这个概念确实很扎实,但是我的问题有点复杂-我试图传递一个带有参数的事件以从外部调用。是的-此参数是使用{#await}
伪造的..所以...用这种方法运气不好
我的第二次尝试:
在了解了更多关于svelte如何处理事件的信息(我是新手,随着我的进步而逐渐发展并学习)之后,我发现了this篇很棒的文章。简而言之:让我们的组件真正面向事件!在您的问题中-您实际上是在尝试实现onload
事件……所以..我们为什么不应该这样做呢?
component.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>
app.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
来响应其他事件-让您为组件构建完整的生命周期令人惊叹!
答案 2 :(得分:0)
Rich 答案的简化版:
<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
。