Naive UI — это современная Vue 3 библиотека компонентов, ориентированная на лёгкость и гибкость использования. Одним из ключевых приёмов оптимизации приложений является динамическая загрузка компонентов, которая позволяет загружать интерфейсные элементы только тогда, когда они действительно необходимы, снижая размер начального бандла и ускоряя время первичной загрузки.
В Vue 3 динамическая загрузка компонентов реализуется через асинхронный импорт:
import { defineAsyncComponent } from 'vue';
const AsyncButton = defineAsyncComponent(() =>
import('naive-ui/lib/button')
);
Пояснение:
defineAsyncComponent принимает функцию, которая
возвращает промис с импортируемым компонентом.Большинство компонентов Naive UI можно загружать динамически. Пример:
<template>
<n-space vertical>
<component :is="AsyncButton" @click="handleClick">Нажми меня</component>
</n-space>
</template>
<script setup>
import { defineAsyncComponent } from 'vue';
import { NSpace } from 'naive-ui';
const AsyncButton = defineAsyncComponent(() =>
import('naive-ui/lib/button')
);
function handleClick() {
console.log('Кнопка нажата');
}
</script>
Ключевые моменты:
n-button загружается только тогда, когда Vue
рендерит AsyncButton.defineAsyncComponent поддерживает дополнительные опции
для управления состояниями загрузки и ошибок:
const AsyncModal = defineAsyncComponent({
loader: () => import('naive-ui/lib/modal'),
loadingComponent: LoadingSpinner,
errorComponent: ErrorMessage,
delay: 200,
timeout: 3000
});
loader — функция импорта компонента.loadingComponent — компонент, отображаемый во время
загрузки.errorComponent — компонент, показываемый при ошибке
загрузки.delay — задержка перед показом
loadingComponent.timeout — максимальное время ожидания загрузки, после
которого отображается ошибка.Такой подход полезен для крупных приложений, где один компонент может весить десятки килобайт.
В связке с Vue Router динамическая загрузка компонентов особенно эффективна для ленивых страниц:
import { createRouter, createWebHistory } from 'vue-router';
const routes = [
{
path: '/dashboard',
component: defineAsyncComponent(() =>
import('pages/DashboardPage.vue')
)
},
{
path: '/settings',
component: defineAsyncComponent(() =>
import('pages/SettingsPage.vue')
)
}
];
const router = createRouter({
history: createWebHistory(),
routes
});
export default router;
SuspenseVue 3 поддерживает компонент Suspense, который облегчает
работу с асинхронными компонентами:
<template>
<Suspense>
<template #default>
<AsyncButton @click="handleClick">Нажми меня</AsyncButton>
</template>
<template #fallback>
<LoadingSpinner />
</template>
</Suspense>
</template>
<script setup>
import { defineAsyncComponent } from 'vue';
import LoadingSpinner from './LoadingSpinner.vue';
const AsyncButton = defineAsyncComponent(() =>
import('naive-ui/lib/button')
);
function handleClick() {
console.log('Нажато');
}
</script>
fallback позволяет показывать индикатор загрузки
до момента, пока компонент полностью не будет готов.n-dialog,
n-popover и n-drawer часто не нужны сразу, их
динамическая загрузка снижает нагрузку на страницу.<template>
<n-space vertical>
<Suspense>
<template #default>
<AsyncTable />
</template>
<template #fallback>
<n-skeleton rows="5" />
</template>
</Suspense>
<Suspense>
<template #default>
<AsyncModal v-model:show="showModal" />
</template>
<template #fallback>
<n-spin />
</template>
</Suspense>
</n-space>
</template>
<script setup>
import { defineAsyncComponent, ref } from 'vue';
import { NSpace, NSkeleton, NSpin } from 'naive-ui';
const showModal = ref(false);
const AsyncTable = defineAsyncComponent(() =>
import('./components/DataTable.vue')
);
const AsyncModal = defineAsyncComponent(() =>
import('naive-ui/lib/modal')
);
</script>
Suspense и компонентов-заполнителей
обеспечивает плавный пользовательский опыт.Динамическая загрузка в Naive UI позволяет не только уменьшить размер бандла, но и улучшить отзывчивость интерфейса, обеспечивая современный подход к построению масштабируемых Vue 3 приложений.