Naive UI предоставляет гибкие инструменты для создания пользовательских интерфейсов, однако вопросы управления доступом и ролями пользователей требуют интеграции с механизмами авторизации. В JavaScript-приложениях на базе Naive UI авторизация чаще всего строится вокруг реактивного состояния, маршрутизации и управления компонентами в зависимости от прав пользователя.
Для отслеживания текущего пользователя и его ролей применяется реактивное состояние, например через Vue 3 Composition API:
import { reactive, computed } from 'vue';
export const userState = reactive({
isAuthenticated: false,
roles: []
});
export const hasRole = (role) => computed(() => userState.roles.includes(role));
isAuthenticated отражает факт входа пользователя.roles содержит массив ролей, например
['admin', 'editor'].hasRole возвращает реактивное булево значение, которое
можно использовать для условного отображения компонентов.Naive UI не предоставляет встроенной системы маршрутизации, но в связке с Vue Router можно организовать доступ к страницам:
import { createRouter, createWebHistory } from 'vue-router';
import { userState } from './userState';
import Home from './pages/Home.vue';
import Admin from './pages/Admin.vue';
import Login from './pages/Login.vue';
const routes = [
{ path: '/', component: Home },
{ path: '/admin', component: Admin, meta: { roles: ['admin'] } },
{ path: '/login', component: Login }
];
const router = createRouter({
history: createWebHistory(),
routes
});
router.beforeEach((to, from, next) => {
const requiredRoles = to.meta.roles;
if (requiredRoles) {
if (!userState.isAuthenticated) {
next('/login');
} else if (!requiredRoles.some(role => userState.roles.includes(role))) {
next('/');
} else {
next();
}
} else {
next();
}
});
export default router;
Ключевые моменты:
meta.roles задаёт роли, которые могут получить доступ к
маршруту.beforeEach проверяет
аутентификацию и роль пользователя.В Naive UI компоненты можно скрывать или изменять их состояние на основе роли пользователя. Например, кнопка, доступная только администраторам:
<template>
<n-button v-if="isAdmin" @click="deleteItem">Удалить</n-button>
</template>
<script setup>
import { hasRole } from './userState';
const isAdmin = hasRole('admin');
function deleteItem() {
console.log('Элемент удален');
}
</script>
Выделенные моменты:
v-if позволяет полностью исключить компонент из DOM,
если пользователь не обладает нужной ролью.computed)
обеспечивает мгновенное обновление интерфейса при изменении ролей.Для проверки токенов и получения данных о ролях обычно используется асинхронный запрос к серверу:
import axios from 'axios';
import { userState } from './userState';
export async function login(username, password) {
try {
const response = await axios.post('/api/login', { username, password });
userState.isAuthenticated = true;
userState.roles = response.data.roles;
} catch (error) {
console.error('Ошибка входа:', error);
userState.isAuthenticated = false;
userState.roles = [];
}
}
Ключевые моменты:
hasRole, автоматически
реагируют на обновление ролей.Часто необходимо отображать меню, зависящее от ролей пользователя:
<template>
<n-menu :options="menuOptions" />
</template>
<script setup>
import { computed } from 'vue';
import { userState } from './userState';
const menuOptions = computed(() => {
const options = [{ label: 'Главная', key: '/' }];
if (userState.roles.includes('admin')) {
options.push({ label: 'Админка', key: '/admin' });
}
if (userState.roles.includes('editor')) {
options.push({ label: 'Редактор', key: '/editor' });
}
return options;
});
</script>
v-if, а не только disabled.Этот подход обеспечивает интеграцию Naive UI с современными системами авторизации и ролевого управления, делая интерфейсы динамичными, безопасными и управляемыми.