---
title: Vue 3 + Naive UI 后台控制台实战：从 0 到可交付
url: https://vabora.dev/posts/vue3-naive-ui-admin
author: Vabora
published: 2026-09-15 11:05:53
updated: 2026-09-26 20:02:28
category: 技术分享
tags: 架构设计, Vue 3, Naive UI
canonical: https://vabora.dev/posts/vue3-naive-ui-admin
license: 转载与引用请注明出处并保留原文链接
---

# Vue 3 + Naive UI 后台控制台实战：从 0 到可交付

> 后台不需要花哨，需要的是稳定、清晰、可维护。这一篇记录我用 Vue 3 + Naive UI 搭博客控制台的完整思路。 技术选型 Vue 3 组合式 API：逻辑复用靠 composable 而不是 mixin Naive UI：主题变量齐全，暗色模式开箱可用 原生 ESM：不上…
后台不需要花哨，需要的是**稳定、清晰、可维护**。这一篇记录我用 Vue 3 + Naive UI 搭博客控制台的完整思路。

## 技术选型

- **Vue 3 组合式 API**：逻辑复用靠 `composable` 而不是 mixin
- **Naive UI**：主题变量齐全，暗色模式开箱可用
- **原生 ESM**：不上构建工具，浏览器直接跑

## 目录约定

```
public/assets/admin/js/
├── api.js        # 请求封装（统一 CSRF / 错误提示）
├── app.js        # 应用入口与路由
└── views/
    ├── dashboard.js
    ├── posts.js
    └── tags.js
```

## 请求封装

统一处理 CSRF 头与 401：

```js
export async function request(path, options = {}) {
  const response = await fetch(path, {
    credentials: 'same-origin',
    headers: {
      'Content-Type': 'application/json',
      'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content,
      ...(options.headers || {}),
    },
    ...options,
  });

  if (response.status === 401) {
    location.href = '/admin/login';
    throw new Error('登录已失效');
  }

  return response.json();
}
```

## 表格 + 分页

Naive UI 的 `n-data-table` 配合远程分页：

```js
const pagination = reactive({
  page: 1,
  pageSize: 15,
  itemCount: 0,
  showSizePicker: true,
  pageSizes: [10, 15, 30, 50],
});
```

## 表单校验

用规则数组而不是模板字符串，便于复用：

```js
const rules = {
  title: { required: true, message: '请输入标题', trigger: 'blur' },
  slug: { required: true, message: '请输入 slug', trigger: 'blur' },
};
```

## 小结

后台的价值在于**让内容生产足够快**。先把文章与标签两条主线跑通，再谈看板与权限。
