8

正如标题所示,我正在尝试将方法从父组件传递给子组件。

例如,

应用程序.html

<div>
  <TodoItem
     done={todo.done}
     toggle={toggle}
  />
</div>
<script>
 import TodoItem from './TodoItem.html';
 export default {
   components: {
     TodoItem,
   },
   methods: {
     toggle(index) {
       console.log(index);
     },
   },
 };
</script>

TodoItem.html

<div>
  <button on:click="toggle(0)"></button>
</div>
<script>
 export default {
   methods: {
     toggle(index) {
       // a guess. this works if you pass in console.log
       this.options.data.toggle(index)
     },
   },
 };
</script>

所需的功能是 TodoItem 使用其数据调用父级的方法。

此示例中断,控制台记录TypeError: this.options.data.toggle is not a function.

4

3 回答 3

17

似乎“火”是 svelte v2 的一部分,但在 svelte v3 中它改变为createEventDispatcher

例如 -

child.svelte

<script>
    import { createEventDispatcher } from 'svelte';

    const dispatch = createEventDispatcher();

    function sayHello() {
        dispatch('message', {
            text: 'Hello!'
        });
    }
</script>

<button on:click={sayHello}>
    Click to say hello
</button>

父母.svelte

<script>
    import Inner from './child.svelte';

    function handleMessage(event) {
        alert(event.detail.text);
    }
</script>

<Inner on:message={handleMessage}/>

欲了解更多信息 - 请访问:https ://svelte.dev/tutorial/component-events

于 2019-12-16T11:03:08.240 回答
14

可以将方法向下传递给子组件但这有点尴尬。更惯用的方法是从子组件触发事件并从父组件侦听该事件:

应用程序.html

<div>
  <TodoItem
    {todo}
    on:toggle="toggle(todo)"
  />
</div>
<script>
  import TodoItem from './TodoItem.html';
  export default {
    components: {
      TodoItem,
    },
    methods: {
      toggle(todo) {
        todo.done = !todo.done;
        const { todos } = this.get();
        this.set({ todos });
     }
   }
 };
</script>

TodoItem.html

<div>
  <button on:click="fire('toggle')">{todo.description}</button>
</div>

如果您需要通过多个级别的组件向上传递事件,您可以重新触发该事件......

<TodoItem on:toggle="fire('toggle', event)">...</TodoItem>

...但是这样做有一个速记,这意味着同样的事情:

<TodoItem on:toggle>...</TodoItem>
于 2018-06-05T17:18:17.700 回答
2

这对我有用。

来自来源

当组件不能没有父级,而父级不能没有组件时很有用

App.svelte

<script>
    import Child from './Child.svelte'
    
    const handleSubmit = value => {
        console.log(value)
    }
</script>

<Child {handleSubmit}/>

苗条的孩子

<script>
    export let handleSubmit
    let value = ''
    
    const onSubmit = e => {
        e.preventDefault()
        handleSubmit(value)
    }
</script>

<form on:submit={onSubmit}>
    <input type="text" bind:value/>
</form>

另一种解决方案是使用上下文

当所有子和孙组件可能调用或可能不调用该函数时很有用。该功能允许所有子和孙组件更新状态/对公共父组件进行更改。

REPL

App.svelte

<script>
    import { getContext, setContext } from 'svelte';
    import Child1 from './Child1.svelte';
    import Child2 from './Child2.svelte';
    
    let counter = 10;
    
    setContext('counter', { increment, decrement });
    
    function increment(delta) {
        counter += delta;
    }
    function decrement(delta) {
        counter -= delta;
    }
</script>

<Child1 />
<Child2 />

<button on:click={() => { increment(10); }}>
    Increment x10
</button>

<div>{counter}</div>

Child1.svelte

<script>
    import { getContext } from 'svelte';
    
    const { increment } = getContext('counter');
</script>

<button on:click={() => increment(1)}>Increment</button>

Child2.svelte

<script>
    import { getContext } from 'svelte';
    
    const { decrement } = getContext('counter');
</script>

<button on:click={() => decrement(1)}>Decrement</button>
于 2022-01-08T13:52:08.487 回答