Не могу передать данные через router.push({query: { projectName }})

пытаюсь передать данные для breadcrumbs при переходе к соответствующему контенту через

router.push({
  name: 'workspace-project-kanban',
  params: {
    workspaceId: props.item.workspaceId,
    projectId: props.item.id,
  },
  query: {
    projectName: projectName
  },
});

и получать его в хуке

const projectName = route.query.projectName as
    | string
    | undefined;

но от постоянно undifined

я просмотрел похожий вопрос: https://stackoverflow.com/questions/40382388/how-to-set-url-query-params-in-vue-with-vue-router Но не смог вынести ничего ясного для себя из него.

вот так выглядит мой router

import { createRouter, createWebHistory } from 'vue-router';

import { hasSessionCookie } from '../../middleware';

const routes = [
    {
        path: '/',
        name: 'greet-page',
        component: () => import('@/pages/auth/GreetPage.vue'),
    },
    {
        path: '/auth',
        name: 'auth',
        component: () => import('@/pages/auth/AuthWrapper.vue'),
        redirect: { name: 'login' },
        children: [
            {
                path: 'login',
                name: 'login',
                component: () => import('@/pages/auth/LoginPage.vue'),
                meta: { isAuthPage: true, title: 'Вход' },
            },
            {
                path: 'register',
                name: 'register',
                component: () => import('@/pages/auth/RegPage.vue'),
                meta: { isAuthPage: true, title: 'Регистрация' },
            },
            {
                path: 'reset-password',
                name: 'reset-password',
                component: () => import('@/pages/auth/ResetPasswordPage.vue'),
                meta: { isAuthPage: true, title: 'Сброс пароля' },
            },
            {
                path: 'new-password',
                name: 'new-password',
                component: () => import('@/pages/auth/NewPasswordPage.vue'),
                meta: { isAuthPage: true, title: 'Установка нового пароля' },
            },
        ],
    },
    {
        path: '/dashboard',
        name: 'dashboard',
        meta: { requiresAuth: true },
        component: () => import('@/pages/dashboard/ui/DashBoard.vue'),
        children: [
            {
                path: 'settings',
                name: 'settings',
                component: () =>
                    import(
                        '@/pages/dashboard/ui/inner/userSettings/ui/UserSettingsPage.vue'
                    ),
                meta: { requiresAuth: true, title: 'Настройки учётной записи' },
            },
            {
                path: 'workspaces',
                name: 'workspaces',
                component: () =>
                    import(
                        '@/pages/dashboard/ui/inner/workspaces/ui/WorkspacesPage.vue'
                    ),
                meta: { requiresAuth: true, title: 'Рабочие области' },
                children: [
                    {
                        path: ':workspaceId',
                        name: 'workspace-details',
                        component: () =>
                            import(
                                '@/pages/dashboard/ui/inner/workspaces/inner/ui/WorkspaceDetailsPage.vue'
                            ),
                        meta: { requiresAuth: true, title: 'Рабочая область' },
                        children: [
                            {
                                path: 'projects/:projectId',
                                name: 'workspace-project-details',
                                component: () =>
                                    import(
                                        '@/pages/dashboard/ui/inner/projects/inner/ui/ProjectDetailsPage.vue'
                                    ),
                                meta: { requiresAuth: true, title: 'Проект' },
                                children: [
                                    {
                                        path: 'tables',
                                        name: 'workspace-project-table',
                                        component: () =>
                                            import(
                                                '@/pages/dashboard/ui/inner/projects/inner/ui/ProjectTablePage.vue'
                                            ),
                                        meta: {
                                            requiresAuth: true,
                                            title: 'Таблица',
                                        },
                                    },
                                    {
                                        path: 'kanban',
                                        name: 'workspace-project-kanban',
                                        component: () =>
                                            import(
                                                '@/pages/dashboard/ui/inner/projects/inner/ui/ProjectKanbanPage.vue'
                                            ),
                                        meta: {
                                            requiresAuth: true,
                                            title: 'Канбан',
                                        },
                                    },
                                    {
                                        path: 'calendar',
                                        name: 'workspace-project-calendar',
                                        component: () =>
                                            import(
                                                '@/pages/dashboard/ui/inner/projects/inner/ui/ProjectCalendarPage.vue'
                                            ),
                                        meta: {
                                            requiresAuth: true,
                                            title: 'Календарь',
                                        },
                                    },
                                ],
                            },
                        ],
                    },
                ],
            },
            {
                path: 'projects',
                name: 'projects',
                component: () =>
                    import(
                        '@/pages/dashboard/ui/inner/projects/ProjectsPage.vue'
                    ),
                meta: { requiresAuth: true, title: 'Рабочие области' },
                children: [
                    {
                        path: ':projectId',
                        name: 'project-details',
                        component: () =>
                            import(
                                '@/pages/dashboard/ui/inner/projects/inner/ui/ProjectDetailsPage.vue'
                            ),
                        meta: { requiresAuth: true, title: 'Проект' },
                    },
                ],
            },
        ],
    },
];

const router = createRouter({
    history: createWebHistory('/'),
    routes,
});

router.beforeEach(async (to) => {
    const hasSession = await hasSessionCookie();

    console.log('Router beforeEach:', {
        to: { path: to.path, params: to.params, query: to.query },
    });

    // Проверка авторизации на страницах auth
    if (to.matched.some((r) => r.meta.isAuthPage)) {
        if (hasSession) return { name: 'dashboard' };
        document.title = (to.meta.title as string) || 'Авторизация';
        return true;
    }

    // Проверка авторизации на защищённых страницах
    if (to.matched.some((r) => r.meta.requiresAuth)) {
        if (!hasSession) {
            return { name: 'login' };
        }
        document.title = (to.meta.title as string) || 'Dashboard';
        return true;
    }

    // Для всех остальных страниц
    document.title = (to.meta.title as string) || 'Agit';
    return true;
});

export default router;

Можно было бы попробовать этот вариант https://stackoverflow.com/a/70204134/23587072 ,но неужели нет способа передать необходимые данные проще?

Я уже задумываюсь об использовании стейт менеджера для хранения этих двух строк.

Я уже проверял данные перед отправкой. Они не undifined и корректны. В route

router.beforeEach(async (to) => {
    const hasSession = await hasSessionCookie();

    console.log('Router beforeEach:', {
        to: { path: to.path, params: to.params, query: to.query }, -- уже undifined
    });

    // Проверка авторизации на страницах auth
    if (to.matched.some((r) => r.meta.isAuthPage)) {
        if (hasSession) return { name: 'dashboard' };
        document.title = (to.meta.title as string) || 'Авторизация';
        return true;
    }

    // Проверка авторизации на защищённых страницах
    if (to.matched.some((r) => r.meta.requiresAuth)) {
        if (!hasSession) {
            return { name: 'login' };
        }
        document.title = (to.meta.title as string) || 'Dashboard';
        return true;
    }

    // Для всех остальных страниц
    document.title = (to.meta.title as string) || 'Agit';
    return true;
});

log консоли касаемо query уже undifined.

Я смутно помню, что уже сталкивался с такой проблемой, итогом которой стала невозможность подобной передачи необходимых query подобным образом через push


Ответы (1 шт):

Автор решения: Project_ Z

Проблема была в том что я некорректно сохранял query. необходимо сохранять переменную в поле объекта.

router.push({
  name: 'workspace-details',
  params: {
    workspaceId: workspace.id
  },
  query: {
    workspaceName: workspaceName
  },
});

Далее, когда мне надо перейти на вложенный маршрут:

const projectName = props.name;
// const workspaceName = props.parentName;
const currentQuery = router.currentRoute.value.query; - сохраняем предыдущие query
console.log('Navigating to project:', {
  workspaceId: props.item.workspaceId,
  projectId: props.item.id,
  projectName: projectName,
  // workspaceName: workspaceName,
});
router.push({
  name: 'workspace-project-kanban',
  params: {
    workspaceId: props.item.workspaceId,
    projectId: props.item.id,
  },
  query: {
    ...currentQuery,
    projectName: projectName,
    // workspaceName: workspaceName,
  },
});

На выходе получаем:

http://localhost:5173/dashboard/workspaces/GUID/projects/GUID/kanban?
**workspaceName=testo&projectName=system**

Хотелось бы ссылку вида:

http://localhost:5173/dashboard/workspaces/GUIDcf&**projectName=system
**/projects/GUID?**workspaceName=testo**/kanban

Но и так сойдёт.

Если кто-то столкнётся с той же проблемой. Пишите, дам более подробный код. Просто используйте Pinia, немного оверхед, в плане реализации Breadcrumbs, но относительно чище и масштабируемее.

UI

Breadcrumbs

→ Ссылка