0

Svelte 3:子组件的道具和数组

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

我的问题是关于子组件通过道具与父母之间的交流。我以前使用商店在旧版本的 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>

编辑器组件负责从我的 redblobgames 六边形处理库的自定义实现中选择布局,设置 SVG 容器并使用图块填充网格。Tis 只是一个调用 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>

当试图在板下方的 teextarea 中显示 thr 选定的瓷砖参考 (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, '')

问题:

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

  • 或者 -

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

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

有谁知道让我走正确的路?

问候,hefeust。

4

1 回答 1

5

您可以使用该指令让父母从孩子那里接收反应性更新- 请参阅此处bind:的文档

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

{#each tiles as {hex, center, corners, selected} }
  <Hex {hex} {center} {corners} bind:selected />
{/each}

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


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

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

希望有帮助!

于 2019-10-01T16:57:06.077 回答