如何保留对循环中创建的组件的引用?
How to keep a reference to component created within a loop?
我正在学习 Svelte,我正在尝试制作一个组件(调色板)。我盲目地寻求一种解决方案,其中每个 ColorSelector
(您单击的颜色 div)都是一个 Svelte 组件。 (我很乐意举一个没有使用子组件的例子)
我在ColorSelector.svelte组件文件中导出了一个selected
属性。我想在单击其中一个时实例化的每个 ColorSelectors 上将 属性 设置为 false
,但已单击的 ColorSelectors 除外。
但是,我正在努力寻找如何在循环中保持对实例化组件的引用。我怎样才能做到这一点?
<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>
要在循环中保留对组件的引用,您可以对数组使用 bind:this
。看看这个问题
为了能够在 option must be activated with <svelte:options accessors={true}/>
Here's a solution with the data flow I assume you were trying to build >> 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>
我正在学习 Svelte,我正在尝试制作一个组件(调色板)。我盲目地寻求一种解决方案,其中每个 ColorSelector
(您单击的颜色 div)都是一个 Svelte 组件。 (我很乐意举一个没有使用子组件的例子)
我在ColorSelector.svelte组件文件中导出了一个selected
属性。我想在单击其中一个时实例化的每个 ColorSelectors 上将 属性 设置为 false
,但已单击的 ColorSelectors 除外。
但是,我正在努力寻找如何在循环中保持对实例化组件的引用。我怎样才能做到这一点?
<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>
要在循环中保留对组件的引用,您可以对数组使用 bind:this
。看看这个问题
为了能够在 option must be activated with <svelte:options accessors={true}/>
Here's a solution with the data flow I assume you were trying to build >> 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>