Настраиваем меню в Svelte, подсвечиваем текущую страницу и создаем в адресной строке url к ссылкам.
Я уже строил меню на готовых решениях, вроде svelte-tabs. Здесь покажу как сделать его своими усилиями. Плюс добавим переходы из браузерной строки на конкретные страницы Svelte.
Идея с переходами по url взята отсюда:
github.com/bluwy/svelte-url
Это небольшой файл url.js, который надо положить к себе.
Index.svelte
Входная страница Index.svelte. В ней мы загружаем наше меню. Оно всегда неизменно и не будет перезагружаться при переходе по ссылкам. Затем добавляем на эту же страницу (она же является главной) обработку url запросов. В зависимости от ссылки указывает страницу перехода. Эти же страницы указаны в меню Nav.svelte.
import url from './assets/js/url'
import Nav from "./Nav.svelte";
import Main from './pages/Main.svelte';
import Page1 from './pages/Page1.svelte';
import Page2 from './pages/Page2.svelte';
</script>
<Nav/>
<!-- Переход из URL на страницы -->
{#if $url.hash === '' || $url.hash === '#/'}
<Main/>
{:else if $url.hash === '#/Page1'}
<Page1/>
{:else if $url.hash === '#/Page2'}
<Page2/>
{:else}
<h1>404</h1>
{/if}
Nav.svelte
Страница с меню и выделения текущей ссылки на Svelte.
Собираем наше меню из нужных нам страниц:
import url from './assets/js/url'
let menu = 0;
let links = [
{
'page': '#/Main',
'name': 'Главная'
},
{
'page': '#/Page1',
'name': 'Название ссылки страницы 1'
},
{
'page': 'Page2',
'name': 'Название ссылки страницы 2'
},
]
// Selected page
let current = '';
let selected;
</script>
Выводим меню на сайте:
{#each links as link, id}
<li>
{#if link.page === 'Main'}
<a href="/#"
class:selected="{$url.hash === ''}"
on:click="{() => current = id}"
on:click={() => menu = id}
>
{link.name}
</a>
{:else}
<a href="#/{link.page}"
class:selected="{$url.hash === link.page}"
on:click="{() => current = id}"
on:click={() => menu = id}
>
{link.name}
</a>
{/if}
</li>
{/each}
</ul>
Добавляем стили scss на Svelte:
//@import 'assets/scss/app';
.menu {
display: flex;
justify-content: space-evenly;
flex-wrap: wrap;
border-bottom: 1px solid #CCCCCC;
margin: 0;
padding: 0;
li {
list-style: none;
display: inline;
}
a {
padding: 0.5em 0.75em;
border-bottom: 2px solid transparent;
cursor: pointer;
list-style: none;
display: inline-block;
&.selected {
border-bottom: 2px solid #4F81E5;
color: #4F81E5;
}
&:hover {
text-decoration: none;
color: darkred;
}
}
}
</style>
За выделение текущей ссылки (страницы) отвечают эти участки:
let current = '';
let selected;
class:selected="{$url.hash === '#/' + link.page}"
on:click="{() => current = id}"
on:click={() => menu = id}
Nav.svelte с иконками
Немного модифицированный вариант под иконки.
JS:
import url from './assets/js/url'
let menu = 0;
let links = [
{
// 'name': 'Графики',
'link': '#/Charts',
'hash': '#/Charts',
'class': 'icon-chart',
},
{
// 'name': 'Главная',
'link': '/#',
'hash': '',
'class': 'icon-add',
},
{
// 'name': 'Админка',
'link': '/admin/',
'class': 'icon-settings'
}
]
// Selected page
let current = '';
let selected;
</script>
Основной код:
{#each links as item, id}
<li class="menu-container js-menu-container">
<a href="{item.link}"
class:selected="{$url.hash === item.hash}"
on:click="{() => current = id}"
on:click={() => menu = id}>
<div class="icon-menu {item.class}"></div>
</a>
</li>
{/each}
</ul>
Стили:
//@import 'assets/scss/app';
.menu {
display: flex;
justify-content: space-evenly;
flex-wrap: wrap;
position: fixed;
z-index: 99;
width: 100%;
margin: 0;
left: 0;
bottom: 0;
background-color: #cdd5e2;
align-items: baseline;
overflow: hidden;
padding: 0;
li {
list-style: none;
display: inline;
}
a {
border-bottom: 2px solid transparent;
cursor: pointer;
list-style: none;
display: inline-block;
padding: 0.5em 0.75em;
color: #000;
&.selected {
border-bottom: 2px solid #4F81E5;
color: #4F81E5;
}
&:hover {
text-decoration: none;
color: darkred;
}
}
.icon-menu {
height: 30px;
width: 30px;
padding: 5px;
cursor: pointer;
}
.icon-chart {
background-color: black;
mask-image: url("");
&:hover {
background-color: red;
}
}
.icon-add {
background-color: black;
mask-image: url("");
mask-repeat: no-repeat;
mask-size: contain;
mask-position: center;
&:hover {
background-color: red;
}
}
.icon-settings {
background-color: black;
mask-image: url("");
mask-repeat: no-repeat;
mask-size: contain;
mask-position: center;
&:hover {
background-color: red;
}
}
}
</style>