Svelte 3:通过道具与父母沟通的孩子数组

Hef*_*ust 0 javascript components svelte sapper

Svelte 3:道具和子组件数组

我计划根据优秀的redblobgames文章在六角形瓷砖上编写棋盘游戏,并使用 Svelte 3 / Sapper 进行编码。

我的问题是关于子组件与父组件之间通过 props 的通信。我以前使用商店在旧版本的 Svelte 中这样做过,但我想没有它也可以做到这一点。

假设我有一块由 herxagons SVG 瓷砖组成的板。每块的形式为:

<script>
  // 3D coordinate system, see: http://redblobgames.org for details
  export let hex = { q:0, r:0, s: 0 }    
  export let center = { x:0, y: 0 }
  export let corners = []
  export let selected = false

  let points = corners.map (c => `${c.x.toFixed(0)},${c.y.toFixed(0)}`).join (' ')

  // changed by selection process (colors...)
  let inner_class = "inner_tile"

  const toggle_select = () => {
    selected = !selected
  }
</script>

<g class="tile" on:click="[ () => toggle_select() }"
  <polygon class={ inner_class} [ points } />

  <!-- more sophisticated things -->
  <!-- sprites, lbels, masks and animations  -->

</g>
Run Code Online (Sandbox Code Playgroud)

编辑器组件负责从我的 redblobgames 六边形处理库的自定义实现中选择布局,设置 SVG 容器并用图块填充网格。这只是一个调用 Hex 组件的 each 语句:

<svg 
  xmlns="www.w3.org/2000/svg"
  viewBox="-50 -50 589 949" 
  width="420"
  height="500"
>
  <!-- just a debugging purpose rectagle ! -->
  <rect x="0" y="0" width="400" height="500" style="fill: none; stroke: black;"/>


  <g class="tiles">
    {#each tiles  as tile }
      <Hex {...tile} />
    {/each}
  </g>  
</svg>

<!-- this helping zone keeps empty, sadly, whatever I attempt to do -->  
<textarea cols="50" rows="10">
  { selected_tiles_output }
</textarea>
Run Code Online (Sandbox Code Playgroud)

当试图在板下方的 teextarea 中显示选定的瓷砖参考(q,r,s)时,问题就出现了。在脚本中执行此操作不起作用:

// imports...

let tiles = []
let selected_tiles = new Set ()
let selected_tiles_output = ''

// onMount to assemlble the board ...

// reactive part which doesn't work:
$: selected_tiles_ouptut = tiles
  .filter (tile => tile.selected)
  .map (tile => tile.hex)
  .map (h => `q: ${h.q}, r: ${h.r}, s: ${h.s} \n`)
  .reduce ((acc, val) => acc + val, '')
Run Code Online (Sandbox Code Playgroud)

题:

父容器是否可以在 childfren 数组中观察某个道具(又名“选定”),即子组件中的一种“柯里化”道具?

  • 或者 -

我应该最终考虑使用商店来代替吗?

注意:在开发的这个阶段,我很难分享一些完整的工作代码示例或源代码,因为它正在发生重大变化。在最坏的情况下,我可以压缩并通过邮件发送 src/routes 和 src/components 工兵的文件夹!

有没有人有想法让我走正确的路?

问候,hefeust。

小智 5

您可以使用bind:指令让父级从子级接收响应式更新- 请参阅此处的文档

看起来您可以在将瓷砖传递给六角形时绑定它们,如下所示:

{#each tiles as {hex, center, corners, selected} }
  <Hex {hex} {center} {corners} bind:selected />
{/each}
Run Code Online (Sandbox Code Playgroud)

然后Editor.svelte应该tile.selectedHex.svelte.


或者,您可以toggle_select在父项中定义Editor而不是 in Hex,并将其作为道具传递给Hex。这样,磁贴的更新直接发生在Editor

<!-- Editor.svelte -->
  <g class="tiles">
    {#each tiles  as tile }
      <Hex {...tile} toggle_select={() => tile.selected = !tile.selected} />
    {/each}
  </g>  
Run Code Online (Sandbox Code Playgroud)
<!-- Hex.svelte -->
<script>
  export let toggle_select
Run Code Online (Sandbox Code Playgroud)

希望有帮助!