Javascript 如何从一个改变组件中某个值的苗条组件导出函数?

Javascript 如何从一个改变组件中某个值的苗条组件导出函数?,javascript,svelte,svelte-component,Javascript,Svelte,Svelte Component,我有一个名为WastedTime.svelte的组件,其值为WastedTime。还有一个函数可以将值更改为50(在我的真实代码中,这是一个动画,但这是堆栈溢出的简化测试用例) 为了允许从父函数调用子函数,我根据Svelte文档使用了: var wastedTime=0; 导出函数changeNumber(){ console.log('正在更改编号') 浪费时间=50 } //将“var wastedTime=0”放在此处也不起作用 浪费的时间:{wastedTime} 父对象从onMou

我有一个名为
WastedTime.svelte
的组件,其值为
WastedTime
。还有一个函数可以将值更改为
50
(在我的真实代码中,这是一个动画,但这是堆栈溢出的简化测试用例)

为了允许从父函数调用子函数,我根据Svelte文档使用了


var wastedTime=0;
导出函数changeNumber(){
console.log('正在更改编号')
浪费时间=50
}
//将“var wastedTime=0”放在此处也不起作用
浪费的时间:{wastedTime}
父对象从
onMount
调用子对象中的函数:


从“svelte”导入{onMount};
从“/WastedTime.svelte”导入WastedTime,{changeNumber};
onMount(()=>{
更改编号()
});
问题在于,由于
中引用了
wastedTime
,因此它似乎无法更改
wastedTime
。导出的函数运行,但
wastedTime
保持为0

我试过: -将
var wastedTime=0
放入
-将
var wastedTime=0
放入

两者都不起作用

如何从一个小巧的组件中导出一个函数来更改组件中的值?

不是被动的-此块中变量的更改不会影响单个实例(除非您更改了存储值,并且每个实例都订阅了该存储)

相反,直接从实例导出
changeNumber
函数,并使用以下方法获取对该函数的引用:

浪费时间

var someNumber=0;
导出函数changeNumber(){
console.log('正在更改编号')
someNumber=56
}
浪费的时间:{someNumber}
App.svelte

从“svelte”导入{onMount};
从“./WastedTime.svelte”导入WastedTime;
让浪费的时间组成;
onMount(()=>{
wastedTimeComponent.changeNumber()
});

这里演示:

好吧,这是一个非常好的问题

我的第一次尝试:

我尝试了@Rich Harris answer(从组件中导出一个函数,在使用带有
onMount
event listener的组件时绑定它)。这个概念确实是可靠的,但我的问题有点复杂——我试图传递一个带有参数的事件,以便从外部调用。是-此参数是使用
{wait}
伪造的。。所以这种方法不走运


我的第二次尝试:

在了解了更多关于svelte如何处理事件的知识后(我是svelte的新手,随着我的进步不断学习),我发现了一篇很棒的文章。简而言之:让我们让我们的组件真正面向事件!在您的问题中-您实际上试图实现
onload
事件。。。所以我们为什么不这样做呢

瘦身


从“svelte”导入{createEventDispatcher,onMount};
const dispatch=createEventDispatcher();
函数doSomething(){console.log('wowza!')}
//等待onMount触发,然后分派名为“load”的事件
onMount(()=>dispatch('load'),
{ 
数据:'耶',
剂量
}));
app.svelte


从“./Component.svelte”导入{Component};
功能组件加载(事件)
{
日志(event.detail.data);
event.detail.doSomething();
}
所以-是的,我今天学到了一些东西!此外:

  • 这是一种更优雅的编码方式(事件驱动)
  • 组件在生命周期内正确使用“苗条事件”来暴露自身
  • dispatch
    可以在响应其他事件时触发-让您为组件构建完整的生命周期

太棒了里奇答案的简化版本:

App.svelte

从“./Time.svelte”导入时间;
让时间成分;
让时间;
花费时间:{time}ms
{#if timeComponent}
timeComponent.spendTime()}>单击我
{:else}
加载。。。
{/if}
时间,苗条

导出var时间=0;
导出函数spendTime(){
时间+=50;
}

这里的关键是
导出功能

谢谢。我发誓我读过文档中的一个例子,上面说从组件导出函数需要
,但我似乎再也找不到了。你可能会想,解释一下1)“从context=“module”脚本块导出的任何东西都会变成从模块本身导出的东西。”和2)“对此块内变量的更改不会影响单个实例”。我是否应该使用
context=“模块”从
脚本导出变量“
还是不?此问题和答案需要放到Svelte文档中!没有解释这个模式,与组件通信是一个三环马戏团。另一种方法是使用导出的函数或作为单独的js类分离WastedTimeService.js中的函数。这使得单元测试功能更加容易。
<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>
<script>
  import { Component } from './component.svelte';

  function component_load(event)
  {
    console.log(event.detail.data);
    event.detail.doSomething();
  }
</script>
<Component on:load={component_load} />
<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}