获取 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>
但是,该列表应该具有相当多的交互性。
- 用户应该能够点击一个项目并且select它
- 只有第一个项目应该是可制表的(
tabindex={0}
)
- 用户应该能够使用箭头键/回车键 select 列表项
- +更多与问题无关的内容
查看 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>
有没有办法遍历 Svelte 组件中的所有子项?
目标
我正在使用这种语法(理想情况下)在 Svelte 中创建一个列表组件。
<List>
<ListItem>Item 1</ListItem>
<ListItem>Item 2</ListItem>
<ListItem>Item 3</ListItem>
</List>
但是,该列表应该具有相当多的交互性。
- 用户应该能够点击一个项目并且select它
- 只有第一个项目应该是可制表的(
tabindex={0}
) - 用户应该能够使用箭头键/回车键 select 列表项
- +更多与问题无关的内容
查看 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>