获取 Svelte 插槽中每个组件的索引

Get index of each component in Svelte slot

有没有办法遍历 Svelte 组件中的所有子项?

目标

我正在使用这种语法(理想情况下)在 Svelte 中创建一个列表组件。

<List>
  <ListItem>Item 1</ListItem>
  <ListItem>Item 2</ListItem>
  <ListItem>Item 3</ListItem>
</List>

但是,该列表应该具有相当多的交互性。

查看 Material Design web components for demos

问题

为此,元素需要知道它们在列表中的“位置”。例如,第一个列表项需要知道它是第一个设置正确的 tabindex。要使用箭头键导航列表,您需要知道“项目 2 处于活动状态”才能在向下箭头上切换到“项目 3”。

有没有办法遍历组件中的所有子项?

或者,一种通过组合实现 Material 设计列表行为的方法?

我知道可以通过使用数据道具而不是合成来实现这一点。但是对于我的用例,长 运行.

中的组合可能会好得多

React 等价物

如果您熟悉 React,我正在寻找像这个令人难以置信的简化示例一样工作的东西。

const List = (props) => {
  return (
    <ul>
      {React.Children.forEach(props.children, (child, index) => (
        child.props.tabIndex = index === 0 ? 0 : -1
      ))}
    </ul>
  )
}

const ListItem = (props) => {
  return <li tabIndex={props.tabIndex}>{props.children}</li>
}

我在下拉菜单组件的父级(您的列表组件)中使用了注册函数。

类似于:

列表组件:

  function nested(nestedText, clicked = false) {
    if (clicked) {
      // clicked and then do something
      ...
    } else {
      // register listItem
      register = [...register, nestedText];
      return register.length - 1;  // itemIdx
    }
  }
  setContext('nested', nested);

项目组成:

let text, itemIdx, thisObj;
const nested = getContext('nested');

onMount(() => {
  text = thisObj.textContent;
  itemIdx = nested(text);  // register item
  ...
});

项目组件html:

<a
  href="..."
  target="..."
  on:click|stopPropagation="{() => {
     nested(text, true);
  }}"
  bind:this={thisObj}>
  <slot />
</a>