如何从 Svelte 的脚本标签内的父级访问组件道具?

时间:2021-05-21 17:02:28

标签: javascript svelte svelte-3

我刚开始使用 Svelte。 我有一个搜索栏组件和该组件的唯一实例:main_searchbar。我想从不同的组件中聚焦该组件。

所以我在 searchbar.svelte 中导出输入:

<script>
    export let value = '';
    export let input;
</script>

<span class="searchbar">
    <input
        class="search"
        type="text"
        name="search"
        bind:value
        bind:this={input}
    >
</span>

然后我在 main_searchbar.svelte 中导入:

<script context="module">
    import Searchbar from './searchbar.svelte';
    export let obj;
</script>

<Searchbar bind:this={obj}/>

然后我创建一个按钮来聚焦:

<script>
        import {obj} from './main_searchbar.svelte';
        
        function focus() {
            obj.input.focus();
        }
</script>

<button on:click={focus}>Focus</button>

最后是 App.svelte:

<script>
    import Main_searchbar from './main_searchbar.svelte'
    import Focus from './focus.svelte'
</script>

<Main_searchbar/>
<Focus/>

当然这行不通: https://svelte.dev/repl/c4eb67950c6240e593173431edb18e1a?version=3.38.2 在 Svelte 中这样做的正确方法是什么?

2 个答案:

答案 0 :(得分:1)

Svelte 附带了 stores,这是一种非常简洁的全局状态管理方式;有了这些,您不必在组件之间传递引用。这是使用可写存储的简化解决方案:

store.js

import { writable } from 'svelte/store';
// An observable string value.
export const focused = writable('');

searchbar.svelte

<script>
    import { focused } from './store'
    export let target;
    let input;
    
    // When the value of the "focused" store is equal to target, 
    //    call focus() on the input.
    focused.subscribe((v) => {
        if(v === target) {
            input.focus()
            // Because subscribe only notifies us of changes,
            //   we have to reset the store or the focus button 
            //   will stop working.
            focused.set('');
        }
    })
</script>

<span class="searchbar">
    <input bind:this={input} />
</span>

focus.svelte

<script>
    import { focused } from './store';
    export let targeting;
        
    // Use the .set() method to set the value of our `focused` store,
    //   triggering all our subscribers (like the one in searchbar.svelte).     
    const focus = () => focused.set(targeting)
</script>

<button on:click={focus}>Focus</button>

App.svelte

<script>
    import Searchbar from './searchbar.svelte'
    import Focus from './focus.svelte'

    // target and targeting must match. 
    // This allows you to reuse the focus component!
</script>

<Searchbar target="search" />
<Focus targeting="search" />

REPL

答案 1 :(得分:0)

要解决您的问题,您可以将以下行添加到 Searchbar.svelte

<svelte:options accessors/>

但是您的设置感觉非常“不成熟”,如果我是您,我会重新考虑架构。

相关问题