【问题标题】:How to keep a reference to component created within a loop?如何保持对循环中创建的组件的引用?
【发布时间】:2022-01-27 05:17:58
【问题描述】:

我正在学习 Svelte,我正在尝试制作一个组件(调色板)。我盲目地寻求一个解决方案,其中每个ColorSelector(您单击的颜色 div)都是一个 Svelte 组件。 (我很乐意举一个不使用子组件的例子)

我在 ColorSelector.svelte 组件文件中导出了 selected 属性。我想在单击其中一个时实例化的每个 ColorSelector 上的该属性设置为 false,但已单击的除外。

但是,我正在努力寻找如何在循环中保持对实例化组件的引用。我怎样才能做到这一点?

<script lang="ts">
  import { Colors, Color } from "./modules/colors";
  import ColorSelector from "./ColorSelector.svelte";

  const DEFAULT_COLOR = Colors.LIGHT_WHITE;
  let selectedColor:Color = DEFAULT_COLOR;

function handleClick(event, i) {
  selectedColor = event.detail.color;
  // When clicked set ColorSelector.selected = false on evert ColorSelectors 
  // except the one that has been clicked
}
</script>

<div>
  {#each Object.values(Colors) as color, i}
    <ColorSelector on:selected={handleSelect} color={color}></ColorSelector>
  {/each}
</div>

<style>
  div {
    display: flex;
  }
</style>

【问题讨论】:

    标签: javascript svelte svelte-3 svelte-component


    【解决方案1】:

    要在循环中保留对组件的引用,您可以将bind:this 用于数组。看看这个问题Svelte how to bind div inside each lop to obtain a reference using this

    为了能够在组件上设置属性,必须使用 &lt;svelte:options accessors={true}/&gt; 激活 option 这是我假设您正在尝试构建的数据流的解决方案 >> REPL

    <script>
        import ColorSelector from './ColorSelector.svelte'
        import {Colors} from './Colors'
        const DEFAULT_COLOR = Colors.LIGHT_WHITE;
    
        let selectedColor = DEFAULT_COLOR
        let colorSelectors = []
    
        function handleSelect(e,i) {
            selectedColor = e.detail.color
            colorSelectors.forEach(cS => cS.selected=false)
            colorSelectors[i].selected = true
        }
    
    </script>
    
    <p><b>{selectedColor}</b></p>
    
    <div>
        {#each Object.values(Colors) as color, i}
        <ColorSelector {color} bind:this={colorSelectors[i]}
                               selected={color === DEFAULT_COLOR ? true : false}
                               on:selected="{(e) => handleSelect(e,i)}"/>
        {/each}
    </div>
    
    <style>
        div {
            display: flex;
            flex-wrap: wrap;
            box-sizing: border-box;
        }
    </style>
    

    [ColorSelector.svelte]

    <svelte:options accessors={true}/>
    
    <script>
        import { createEventDispatcher } from 'svelte';
        const dispatch = createEventDispatcher();
        
        export let color, selected  
    
        function handleClick() {
            dispatch('selected', {
                color
            });
        }
    </script>
    
    <div class="color-selector"
             class:selected
             style:background={color}            
             on:click={handleClick}
        ></div>
    
    <style>
        .color-selector {
            flex-basis: 200px;
            flex-grow: 1;
            height: 100px;
            box-sizing: border-box;
        }
        .selected {
            border: 5px solid black;
        }
    </style>
    
    
    

    但我认为构建选择器并不真正需要这些功能,selected = true/false 标志也不是,因为只有一种选定的颜色很重要。 这是一个更简单的解决方案,有和没有组件REPL

    <script>
        import ColorSelector from './ColorSelector.svelte'
        import {Colors} from './Colors'
        const DEFAULT_COLOR = Colors.LIGHT_WHITE;
        let selectedColor = DEFAULT_COLOR;
    </script>
    
    <p><b>{selectedColor}</b></p>
    
    <div>
        {#each Object.values(Colors) as color, i}
        <div class="color-selector"
                 class:selected-color={selectedColor === color}
                 style:background={color}            
                 on:click={() => selectedColor = color}
            ></div>
        {/each}
    </div>
    
    <hr>
    
    <div>
        {#each Object.values(Colors) as color, i}
        <ColorSelector {color} bind:selectedColor />
        {/each}
    </div>
    
    <style>
        div {
            display: flex;
            flex-wrap: wrap;
            box-sizing: border-box;
        }
        .color-selector {
            flex-basis: 200px;
            flex-grow: 1;
            height: 100px;
        }
        .selected-color {
            border: 5px solid black;
        }
        hr {
            margin: 3rem;
        }
    </style>
    

    [ColorSelector.svelte]

    <script>
        export let color, selectedColor
    </script>
    
    <div class="color-selector"
             class:selected-color={selectedColor === color}
             style:background={color}            
             on:click={() => selectedColor = color}
        ></div>
    
    <style>
        .color-selector {
            flex-basis: 200px;
            flex-grow: 1;
            height: 100px;
            box-sizing: border-box;
        }
        .selected-color {
            border: 5px solid black;
        }
    </style>
    

    【讨论】:

      猜你喜欢
      • 2022-09-22
      • 1970-01-01
      • 2023-03-25
      • 2019-08-25
      • 1970-01-01
      • 2022-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多