Фреймворк Накст

Файл-бейзед рутинг в Наксте: простое правило

Рутинг Накста устроен так, что родительские руты имеют приоритет над дочерними: ~/pages/foo.vue > ~/pages/foo/[slug].vue. Поскольку Накст считает [slug].vue дочерним рутом, для его отображения необходим компонент <NuxtPage>. Иначе [slug].vue никогда не зарендерится.

Если вам в голову пришёл хак рендерить основную страницу, а в конце дописывать <NuxtPage v-else>, отслеживая имя рута, — не надо. Компоненты начнут прокидываться фрагментами, возникнет ошибка parent is null, из-за неё целиком пропадёт страница. Избавьте себя от проблем с рендерингом.

Что говорит дока

Дока рекомендует писать так: ~/pages/foo/index.vue и ~/pages/foo/[slug].vue. Файлы index.vue позволяют отловить все руты уровнем ниже и перейти на них.

Но если страница описана в index.vue, рут не считается дочерним (children). Так как useRoute().matched полагается на дочерние руты, это ломает класс active в ссылках <NuxtLink> и <RouterLink>.

Знатоки Накста предлагают ввести такую структуру папок:

/pages
  /posts
    [postId].vue
    index.vue
  posts.vue

Где posts.vue содержит код:

<template>
	<NuxtPage />
</template>

К сожалению, это приводит к дублированию рутов и всё к тому же parent is null. Если вывести в консоль useRouter().getRoutes(), вы увидите, что в поле matched выводятся по два рута с одинаковым именем, но один из них содержит null.

Знатоки предлагают обернуть каждый <NuxtPage /> дивом, чтобы заполнить null и положить фрагменты в корневой элемент, но это полумера. К тому же, пока по всему проекту насоздаёшь этих файлов по три строчки, заработаешь геморрой.

Предлагаю написать функцию, которая определит активность ссылки по текущему URL:

// shared/lib/isLinkActiveFor.ts
export function isLinkActiveFor(pagePath: string) {
	return useRoute().path.startsWith(pagePath)
}

Использование:

<NuxtLink
	:to="link.href"
	class="header__link p-text-lg--medium"
	:class="{ 'header__link--active': isLinkActiveFor(link.href) }"
>
	{{ link.title }}
</NuxtLink>

На useRoute().matched ещё зачастую полагается компонент хлебных крошек, но его легко написать через дробление URL:

«единственный рабочий вариант для Nuxt 3»

Создавайте страницы вида static.vue и [slug].vue в двух случаях:

В остальных случаях используйте index.vue.

Ещё

Is index.vue always requested? Как отловить корневой рут и вложенные в одном файле.

Прожмите реакцию