如何解决Svelte 中的分段控制组件——如何获取同级组件的宽度和偏移量
我正在尝试编写一个 svelte 组件,它的行为类似于分段控制菜单(如连续性部分下的 here)。由于我是 svelte 的新手,为了使任务更容易,我重新使用了一些 IBM 的 open-sourced code。
这是目前的代码:
// App.js
<script>
import { SegmentedControl,Segment,SegmentBackground } from './components/SegmentedControl';
</script>
<SegmentedControl>
<Segment text="Latest news" id='segment-latest-news' />
<Segment text="Trending" id='segment-trending' />
<SegmentBackground />
</SegmentedControl>
// SegmentedControl.svelte
<script>
export let selectedindex = 0;
import { afterUpdate,createEventdispatcher,setContext } from 'svelte';
import { writable } from 'svelte/store';
const dispatch = createEventdispatcher();
const currentId = writable(null);
$: currentIndex = -1;
$: segments = [];
$: if (segments[currentIndex]) {
dispatch('change',currentIndex);
currentId.set(segments[currentIndex].id);
}
setContext('SegmentedControl',{
currentId,add: ({ id,text,selected }) => {
if (selected) {
selectedindex = segments.length;
}
segments = [...segments,{ id,selected }];
},update: (id) => {
selectedindex = segments.map(({ id }) => id).indexOf(id);
},});
afterUpdate(() => {
if (selectedindex !== currentIndex) {
currentIndex = selectedindex;
}
});
</script>
<div
role='tablist'
class:segmented-control='{true}'
{...$$restProps}
on:click
>
<slot />
</div>
// Segment.svelte
<script>
export let text = '';
export let selected = false;
export let disabled = false;
export let id = '';
export let ref = null;
import { afterUpdate,getContext,onDestroy } from 'svelte';
const ctx = getContext('SegmentedControl');
ctx.add({ id,selected });
const unsubscribe = ctx.currentId.subscribe(($) => {
selected = $ === id;
});
afterUpdate(() => {
if (selected) {
ref.focus();
}
});
onDestroy(() => {
unsubscribe();
});
</script>
<button
bind:this='{ref}'
role='tab'
tabindex='{selected ? '0' : '-1'}'
aria-selected='{selected}'
disabled='{disabled}'
id='{id}'
class:segmented-control-btn='{true}'
class:segmented-control--selected='{selected}'
{...$$restProps}
on:click
on:click|preventDefault='{() => {
ctx.update(id);
}}'
>
<span class:segmented-control__label='{true}'>
<slot>{text}</slot>
</span>
</button>
// SegmentBackground.svelte (practically empty)
<script></script>
<div class:segmented-control--bg='{true}'></div>
<style>
.segmented-control--bg {
position: absolute;
top: .175em;
left: .175em;
z-index: -1;
height: 2em;
min-width: 2em;
background: #111;
transition: 300ms;
}
</style>
我已将 SegmentBackground
组件添加到 IBM 的代码中,我希望它更改 width
和 offsetLeft
以匹配选定的 Segment
组件。但我不知道如何访问这些数据。
我已经有一段时间不知道如何解决这个问题了。如果有人能告诉或暗示如何去做,我将不胜感激。
谢谢
编辑:或者为 SegmentedControl
组件添加背景可能更好?
解决方法
我解决这个问题的方法是还将对按钮元素的引用传递给 SegmentedControl,一旦你有了这个,你就可以将 selectedIndex 和这个引用结合到获取实际的活动按钮。从按钮使用 getBoundingClientRect
获取按钮的位置,并以某种方式将其传递给背景,以便它可以自行定位。
检查这个 REPL 以获得快速和肮脏的实现。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。