如何在 <svelte:this> 递归文件夹树上使用 isActive class?
How to use an isActive class on <svelte:this> recurisve folder tree?
我正在构建递归文件夹结构,希望能够通过切换 class 来突出显示单击的文件夹。以便用户知道他们点击了哪个文件夹。
我已经成功完成了,但是当使用 sveltes 递归元素时 <svelte:this>
没有按预期工作。似乎每个递归文件夹都在它自己的范围内。
错误的结果是每个文件夹突出显示都是自己的文件。
我只想在任何给定时间激活一个文件。
我错过了什么?
我尝试将 <svelte:this>
组件移动到不同的位置。
所有数据都按预期传递。
REPL
这重现了问题。我的实际项目中的代码略有不同 - 但问题是一样的。
https://svelte.dev/repl/0f91294a827342e7b6b99d33576da909?version=3.38.3
原始示例(精巧的文档)
https://svelte.dev/tutorial/svelte-self
<script>
// App.svelte
import Folder from './Folder.svelte';
let root = [
{
type: 'folder',
name: 'Animal GIFs',
files: [
{
type: 'folder',
name: 'Dogs',
files: [
{ type: 'file', name: 'treadmill.gif' },
{ type: 'file', name: 'rope-jumping.gif' }
]
},
{
type: 'folder',
name: 'Goats',
files: [
{ type: 'file', name: 'parkour.gif' },
{ type: 'file', name: 'rampage.gif' }
]
},
{ type: 'file', name: 'cat-roomba.gif' },
{ type: 'file', name: 'duck-shuffle.gif' },
{ type: 'file', name: 'monkey-on-a-pig.gif' }
]
},
{ type: 'file', name: 'TODO.md' },
{ type: 'file', name: 'Readme.md' }
];
</script>
<Folder name="Home" files={root} expanded/>
<script>
// Folder.svelte
import File from './File.svelte';
export let expanded = false;
export let name;
export let files;
let isActive = ""
function toggle() {
expanded = !expanded;
}
function activate(event) {
console.log(event)
isActive = event
}
</script>
<span class:expanded on:click={toggle}>{name}</span>
{#if expanded}
<ul>
{#each files as file}
<li>
{#if file.type === 'folder'}
<svelte:self {...file}/>
{:else}
<div on:click={activate(file.name)}>
<File {...file} {isActive} />
</div>
{/if}
</li>
{/each}
</ul>
{/if}
<style>
span {
padding: 0 0 0 1.5em;
background: url(tutorial/icons/folder.svg) 0 0.1em no-repeat;
background-size: 1em 1em;
font-weight: bold;
cursor: pointer;
}
.expanded {
background-image: url(tutorial/icons/folder-open.svg);
}
ul {
padding: 0.2em 0 0 0.5em;
margin: 0 0 0 0.5em;
list-style: none;
border-left: 1px solid #eee;
}
li {
padding: 0.2em 0;
}
</style>
<script>
// File.svelte
export let name;
export let isActive = ""
$: type = name.slice(name.lastIndexOf('.') + 1);
</script>
<span
class:active={isActive === name}
style="background-image: url(tutorial/icons/{type}.svg)">
{name}
</span>
<style>
span {
padding: 0 0 0 1.5em;
background: 0 0.1em no-repeat;
background-size: 1em 1em;
}
.active {
color: orange;
font-weight: bold;
}
</style>
您可以使用可写存储来保存 isActive
,这样组件的每次迭代都不会获得它自己的私有 isActive
变量。
这是一个有效的 REPL https://svelte.dev/repl/7d4c7b8ee006484489d5141b04ae163c?version=3.38.3
我正在构建递归文件夹结构,希望能够通过切换 class 来突出显示单击的文件夹。以便用户知道他们点击了哪个文件夹。
我已经成功完成了,但是当使用 sveltes 递归元素时 <svelte:this>
没有按预期工作。似乎每个递归文件夹都在它自己的范围内。
错误的结果是每个文件夹突出显示都是自己的文件。
我只想在任何给定时间激活一个文件。
我尝试将 <svelte:this>
组件移动到不同的位置。
所有数据都按预期传递。
REPL 这重现了问题。我的实际项目中的代码略有不同 - 但问题是一样的。 https://svelte.dev/repl/0f91294a827342e7b6b99d33576da909?version=3.38.3
原始示例(精巧的文档) https://svelte.dev/tutorial/svelte-self
<script>
// App.svelte
import Folder from './Folder.svelte';
let root = [
{
type: 'folder',
name: 'Animal GIFs',
files: [
{
type: 'folder',
name: 'Dogs',
files: [
{ type: 'file', name: 'treadmill.gif' },
{ type: 'file', name: 'rope-jumping.gif' }
]
},
{
type: 'folder',
name: 'Goats',
files: [
{ type: 'file', name: 'parkour.gif' },
{ type: 'file', name: 'rampage.gif' }
]
},
{ type: 'file', name: 'cat-roomba.gif' },
{ type: 'file', name: 'duck-shuffle.gif' },
{ type: 'file', name: 'monkey-on-a-pig.gif' }
]
},
{ type: 'file', name: 'TODO.md' },
{ type: 'file', name: 'Readme.md' }
];
</script>
<Folder name="Home" files={root} expanded/>
<script>
// Folder.svelte
import File from './File.svelte';
export let expanded = false;
export let name;
export let files;
let isActive = ""
function toggle() {
expanded = !expanded;
}
function activate(event) {
console.log(event)
isActive = event
}
</script>
<span class:expanded on:click={toggle}>{name}</span>
{#if expanded}
<ul>
{#each files as file}
<li>
{#if file.type === 'folder'}
<svelte:self {...file}/>
{:else}
<div on:click={activate(file.name)}>
<File {...file} {isActive} />
</div>
{/if}
</li>
{/each}
</ul>
{/if}
<style>
span {
padding: 0 0 0 1.5em;
background: url(tutorial/icons/folder.svg) 0 0.1em no-repeat;
background-size: 1em 1em;
font-weight: bold;
cursor: pointer;
}
.expanded {
background-image: url(tutorial/icons/folder-open.svg);
}
ul {
padding: 0.2em 0 0 0.5em;
margin: 0 0 0 0.5em;
list-style: none;
border-left: 1px solid #eee;
}
li {
padding: 0.2em 0;
}
</style>
<script>
// File.svelte
export let name;
export let isActive = ""
$: type = name.slice(name.lastIndexOf('.') + 1);
</script>
<span
class:active={isActive === name}
style="background-image: url(tutorial/icons/{type}.svg)">
{name}
</span>
<style>
span {
padding: 0 0 0 1.5em;
background: 0 0.1em no-repeat;
background-size: 1em 1em;
}
.active {
color: orange;
font-weight: bold;
}
</style>
您可以使用可写存储来保存 isActive
,这样组件的每次迭代都不会获得它自己的私有 isActive
变量。
这是一个有效的 REPL https://svelte.dev/repl/7d4c7b8ee006484489d5141b04ae163c?version=3.38.3