{"_id":"@flecblog/core-nuxt","_rev":"135-d1b0cc8d1c6c1992bc74149d4b353f58","name":"@flecblog/core-nuxt","dist-tags":{"latest":"1.0.1"},"versions":{"0.8.0":{"name":"@flecblog/core-nuxt","version":"0.8.0","keywords":["flecblog","nuxt","layer","theme"],"author":{"name":"FlecBlog"},"license":"MIT","_id":"@flecblog/core-nuxt@0.8.0","maintainers":[{"name":"talen2004","email":"talen2004@163.com"}],"dist":{"shasum":"80d793d069bac0f6d72d9bb67f918fb6e5740884","tarball":"https://registry.npmjs.org/@flecblog/core-nuxt/-/core-nuxt-0.8.0.tgz","fileCount":70,"integrity":"sha512-Lj3Uohq4uGfDfIeLBXMznQs0jaMTk9KMbXKL9E+U8soUX9IfoR9x1P9Sb9/Xh/f0S2pFAwYaJugVpUMQeaCBOg==","signatures":[{"sig":"MEUCIQCIgoYOr2gNUlFgzevy/P7Pm1Esc520XDQ8qR7aWFy+XQIgHRt/elkhTABWtuML5TAd+KjX8iuW+XVYt2jUgZ8tIV0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":185022},"main":"./nuxt.config.ts","type":"module","types":"./types/index.ts","exports":{".":{"types":"./types/index.ts","import":"./nuxt.config.ts"},"./types/*":"./types/*"},"gitHead":"5b534ac6038ef0a0927d1342976b87dc79e59607","_npmUser":{"name":"talen2004","email":"talen2004@163.com"},"_npmVersion":"10.9.3","description":"FlecBlog Core - Nuxt Layer for theme development","directories":{},"_nodeVersion":"22.20.0","dependencies":{"dayjs":"^1.11.13","katex":"^0.16.45","mermaid":"^11.12.3","entities":"^7.0.1","dompurify":"^3.3.1","remixicon":"^4.9.1","@nuxt/image":"^2.0.0","@nuxtjs/seo":"^5.3.0","markdown-it":"^14.1.1","@vueuse/core":"^14.3.0","@vueuse/nuxt":"^14.3.0","highlight.js":"^11.11.1","markdown-it-kbd":"^3.0.2","markdown-it-sub":"^2.0.0","markdown-it-sup":"^2.0.0","markdown-it-mark":"^4.0.0","markdown-it-anchor":"^9.2.0","isomorphic-dompurify":"^3.0.0","markdown-it-task-lists":"^2.1.1","markdown-it-link-attributes":"^4.0.1","markdown-it-plugin-underline":"^0.0.1","@traptitech/markdown-it-katex":"^3.6.0"},"_hasShrinkwrap":false,"devDependencies":{"@types/markdown-it":"^14.1.2"},"peerDependencies":{"vue":"^3.0.0","nuxt":"^4.0.0"},"_npmOperationalInternal":{"tmp":"tmp/core-nuxt_0.8.0_1782529264627_0.31431274308587254","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"@flecblog/core-nuxt","version":"1.0.0","keywords":["flecblog","nuxt","layer","theme"],"author":{"name":"FlecBlog"},"license":"MIT","_id":"@flecblog/core-nuxt@1.0.0","maintainers":[{"name":"talen2004","email":"talen2004@163.com"}],"dist":{"shasum":"97077924b87c8542228d4f669f4ccbcdf0cb36ed","tarball":"https://registry.npmjs.org/@flecblog/core-nuxt/-/core-nuxt-1.0.0.tgz","fileCount":70,"integrity":"sha512-cQWmqfhJWykSi9A6VCXZXY0nBwyBqKi+pGqAS+jdx9AvILgDh3hU/Qk3Bhz1g0gfyN8UWBWUHl1ffoidpak1Rw==","signatures":[{"sig":"MEQCIAzhjFO6ks/n0OiNrgEnydU+bMZT0TiLGEZsa8gO4xvoAiBbGVQxwH5xFZlWSQR0h62QnTvlMgE6kARZX+y0qvAzHg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":178757},"main":"./nuxt.config.ts","type":"module","types":"./types/index.ts","exports":{".":{"types":"./types/index.ts","import":"./nuxt.config.ts"},"./types/*":"./types/*"},"gitHead":"ef57d3cff98a352bb8a72c0632d6d335dc9297d5","_npmUser":{"name":"talen2004","email":"talen2004@163.com"},"_npmVersion":"10.9.8","description":"FlecBlog Core - Nuxt Layer for theme development","directories":{},"_nodeVersion":"22.23.0","dependencies":{"dayjs":"^1.11.13","katex":"^0.16.45","mermaid":"^11.12.3","entities":"^7.0.1","dompurify":"^3.3.1","remixicon":"^4.9.1","@nuxt/image":"^2.0.0","@nuxtjs/seo":"^5.3.0","markdown-it":"^14.1.1","@vueuse/core":"^14.3.0","@vueuse/nuxt":"^14.3.0","highlight.js":"^11.11.1","markdown-it-kbd":"^3.0.2","markdown-it-sub":"^2.0.0","markdown-it-sup":"^2.0.0","markdown-it-mark":"^4.0.0","markdown-it-anchor":"^9.2.0","isomorphic-dompurify":"^3.0.0","markdown-it-task-lists":"^2.1.1","markdown-it-link-attributes":"^4.0.1","markdown-it-plugin-underline":"^0.0.1","@traptitech/markdown-it-katex":"^3.6.0"},"_hasShrinkwrap":false,"devDependencies":{"@types/markdown-it":"^14.1.2"},"peerDependencies":{"vue":"^3.0.0","nuxt":"^4.0.0"},"_npmOperationalInternal":{"tmp":"tmp/core-nuxt_1.0.0_1782539767899_0.3395622720792706","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"_id":"@flecblog/core-nuxt@1.0.1","dist":{"shasum":"5bcdb560f036dd1948e97d055cef34f21a7da383","tarball":"https://registry.npmjs.org/@flecblog/core-nuxt/-/core-nuxt-1.0.1.tgz","fileCount":70,"integrity":"sha512-MGgJ+GBPDUWe8rwSPwHetftlAuWaWmud7kgNm53Wm5qoak+XEx6n7ixb/6Ynr4bB3Gb3ZcsIIwerf6deGU/+JA==","signatures":[{"sig":"MEYCIQDvw55AyoMu8bGuXfOsbge7ZEby6umU6CIRjwE5AMzhcgIhAIv7nc3XhE05JGbSXul4wE3mWZEttOuCjaVgE3Ez0tom","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIGIpXPyXvAz/v6CplqbIEaxXVLLdwnftZgT8OAR1i2N6AiEA66ID3l32FdvZrJc1v22RlGJ9beMf/hgVgymQWoeMj9c="}],"unpackedSize":177663},"main":"./nuxt.config.ts","name":"@flecblog/core-nuxt","type":"module","types":"./types/index.ts","author":{"name":"FlecBlog"},"exports":{".":{"types":"./types/index.ts","import":"./nuxt.config.ts"},"./types/*":"./types/*"},"gitHead":"76a7dfee9c1f78f9a84321fbad8a6423904b953f","license":"MIT","version":"1.0.1","_npmUser":{"name":"talen2004","email":"talen2004@163.com"},"keywords":["flecblog","nuxt","layer","theme"],"_npmVersion":"10.9.8","description":"FlecBlog Core - Nuxt Layer for theme development","directories":{},"maintainers":[{"name":"talen2004","email":"talen2004@163.com"}],"_nodeVersion":"22.23.2","dependencies":{"dayjs":"^1.11.13","katex":"^0.16.45","mermaid":"^11.12.3","entities":"^7.0.1","dompurify":"^3.3.1","remixicon":"^4.9.1","@nuxt/image":"^2.0.0","@nuxtjs/seo":"^5.3.0","markdown-it":"^14.1.1","@vueuse/core":"^14.3.0","@vueuse/nuxt":"^14.3.0","highlight.js":"^11.11.1","markdown-it-kbd":"^3.0.2","markdown-it-sub":"^2.0.0","markdown-it-sup":"^2.0.0","markdown-it-mark":"^4.0.0","markdown-it-anchor":"^9.2.0","isomorphic-dompurify":"^3.0.0","markdown-it-task-lists":"^2.1.1","markdown-it-link-attributes":"^4.0.1","markdown-it-plugin-underline":"^0.0.1","@traptitech/markdown-it-katex":"^3.6.0"},"_hasShrinkwrap":false,"devDependencies":{"@types/markdown-it":"^14.1.2"},"peerDependencies":{"vue":"^3.0.0","nuxt":"^4.0.0"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/core-nuxt_1.0.1_1790349181634_0.5784446016846041"}}},"time":{"created":"2026-06-17T02:54:13.559Z","modified":"2026-09-25T15:13:01.902Z","0.1.0":"2026-06-17T02:54:13.835Z","0.1.1":"2026-06-17T05:53:50.480Z","0.1.2":"2026-06-17T09:58:51.953Z","0.1.3":"2026-06-17T11:23:26.619Z","0.1.4":"2026-06-17T13:04:11.960Z","0.1.5":"2026-06-17T13:10:57.228Z","0.1.6":"2026-06-17T13:31:30.102Z","0.1.7":"2026-06-17T13:39:50.404Z","0.1.8":"2026-06-17T13:45:17.565Z","0.1.9":"2026-06-17T14:38:42.658Z","0.1.10":"2026-06-17T14:44:06.654Z","0.1.11":"2026-06-17T14:47:06.323Z","0.1.12":"2026-06-17T15:06:02.817Z","0.2.0":"2026-06-22T03:19:41.560Z","0.2.1":"2026-06-22T03:29:42.217Z","0.2.2":"2026-06-22T03:36:37.628Z","0.2.3":"2026-06-22T03:41:50.162Z","0.2.4":"2026-06-22T03:44:47.728Z","0.2.5":"2026-06-22T04:02:00.576Z","0.2.6":"2026-06-22T04:05:54.322Z","0.2.7":"2026-06-22T04:09:21.774Z","0.2.8":"2026-06-22T04:19:28.378Z","0.2.9":"2026-06-22T04:20:19.535Z","0.2.10":"2026-06-22T04:21:08.837Z","0.2.11":"2026-06-22T04:25:05.125Z","0.2.12":"2026-06-22T04:27:06.437Z","0.2.13":"2026-06-22T04:30:57.463Z","0.2.14":"2026-06-22T04:34:06.505Z","0.2.15":"2026-06-22T04:41:21.376Z","0.2.16":"2026-06-22T04:42:34.534Z","0.2.17":"2026-06-22T04:47:00.037Z","0.2.18":"2026-06-22T04:49:35.009Z","0.2.19":"2026-06-22T04:59:30.274Z","0.2.20":"2026-06-22T05:06:51.129Z","0.2.21":"2026-06-22T05:11:19.636Z","0.2.22":"2026-06-22T05:17:48.470Z","0.2.23":"2026-06-22T05:24:55.840Z","0.2.24":"2026-06-22T05:26:52.573Z","0.2.25":"2026-06-22T05:28:24.667Z","0.2.26":"2026-06-22T05:30:21.344Z","0.2.27":"2026-06-22T05:31:10.289Z","0.2.28":"2026-06-22T05:36:22.314Z","0.2.29":"2026-06-22T05:37:12.083Z","0.2.30":"2026-06-22T05:37:51.574Z","0.2.31":"2026-06-22T05:48:27.167Z","0.2.32":"2026-06-22T05:50:53.463Z","0.2.33":"2026-06-22T05:51:34.158Z","0.2.34":"2026-06-22T05:59:55.881Z","0.3.0":"2026-06-22T08:21:49.766Z","0.3.1":"2026-06-22T08:49:09.271Z","0.3.2":"2026-06-22T09:13:53.460Z","0.3.3":"2026-06-22T09:23:13.771Z","0.3.4":"2026-06-22T10:07:24.924Z","0.3.5":"2026-06-22T10:34:11.227Z","0.3.6":"2026-06-22T10:52:37.533Z","0.3.7":"2026-06-23T01:51:41.687Z","0.3.8":"2026-06-23T05:09:23.360Z","0.5.0":"2026-06-23T05:21:26.493Z","0.6.0":"2026-06-23T07:54:40.961Z","0.6.1":"2026-06-24T05:42:13.873Z","0.6.2":"2026-06-24T06:05:06.549Z","0.6.3":"2026-06-24T06:10:08.402Z","0.6.4":"2026-06-24T06:26:15.684Z","0.6.5":"2026-06-24T06:33:10.670Z","0.7.0":"2026-06-27T02:52:14.922Z","0.7.1":"2026-06-27T02:58:09.286Z","0.8.0":"2026-06-27T03:01:04.769Z","1.0.0":"2026-06-27T05:56:08.049Z","1.0.1":"2026-09-25T15:13:01.724Z"},"author":{"name":"FlecBlog"},"license":"MIT","keywords":["flecblog","nuxt","layer","theme"],"description":"FlecBlog Core - Nuxt Layer for theme development","maintainers":[{"name":"talen2004","email":"talen2004@163.com"}],"readme":"# @flecblog/core-nuxt\n\nFlecBlog 主题开发核心包。创建主题时只需 `extends` 此包，即可获得自动导入的函数、开箱即用的文章排版、完整的 TypeScript 类型。\n\n## 快速开始\n\n```bash\nnpm install @flecblog/core-nuxt\n```\n\n在主题的 `nuxt.config.ts` 中：\n\n```ts\nexport default defineNuxtConfig({\n  extends: ['@flecblog/core-nuxt'],\n})\n```\n\n## 函数\n\n安装后在 `.vue` / `.ts` 文件中直接调用，无需 import。\n\n### 文章\n\n| 函数 | 说明 | 示例 |\n|---|---|---|\n| `useCurrentArticle` | 获取当前文章 | `const { currentArticle } = useCurrentArticle()` |\n| `useArticle` | 按 slug 获取文章 | `const { data: article, refresh } = useArticle(slug)` |\n| `useArticleList` | 分页获取文章列表 | `const { data: articles, page } = useArticleList()` |\n| `useSearch` | 搜索文章 | `const { results, search } = useSearch()` |\n| `useRandomArticle` | 获取随机文章 | `const { go } = useRandomArticle()` |\n| `getArticleList` | API：文章列表 | `await getArticleList({ page: 1 })` |\n| `getArticleBySlug` | API：按 slug 获取 | `await getArticleBySlug('hello-world')` |\n| `searchArticles` | API：搜索 | `await searchArticles({ keyword: 'vue' })` |\n| `getRandomArticleSlug` | API：随机 slug | `await getRandomArticleSlug()` |\n\n### 认证\n\n| 函数 | 说明 | 示例 |\n|---|---|---|\n| `isLoggedIn` | 响应式登录状态 | `v-if=\"isLoggedIn\"` |\n| `useAuth` | 获取登录状态 | `const isAuth = useAuth()` |\n| `useAuthActions` | 登录/注册/找回密码 | `const { loginUser } = useAuthActions()` |\n| `useLoginModal` | 控制登录弹窗 | `const { open } = useLoginModal()` |\n| `useBindEmail` | 邮箱绑定提示 | `const { triggerGlobal } = useBindEmail()` |\n| `accessToken` | 当前 token（ref） | `headers['Authorization'] = \\`Bearer ${accessToken.value}\\`` |\n| `setAccessToken` | 设置 token | `setAccessToken(token)` |\n| `getAccessToken` | 读取 token | `const t = getAccessToken()` |\n| `clearAccessToken` | 清除 token | `clearAccessToken()` |\n| `logoutUser` | 登出 | `logoutUser()` |\n| `login` | API：登录 | `await login({ email, password })` |\n| `register` | API：注册 | `await register({ email, nickname, password })` |\n| `refreshToken` | API：刷新 token | `await refreshToken()` |\n| `forgotPassword` | API：发送验证码 | `await forgotPassword({ email })` |\n| `resetPassword` | API：重置密码 | `await resetPassword({ email, code, password })` |\n| `logout` | API：服务端登出 | `await logout()` |\n| `getOAuthUrl` | API：OAuth 登录地址 | `getOAuthUrl('github', redirect)` |\n| `getOAuthBindUrl` | API：OAuth 绑定地址 | `getOAuthBindUrl('github', redirect)` |\n| `getWechatQrcode` | API：微信扫码登录 | `const { blob, scene } = await getWechatQrcode()` |\n| `getWechatScene` | API：轮询扫码状态 | `await getWechatScene(scene)` |\n\n### 用户\n\n| 函数 | 说明 | 示例 |\n|---|---|---|\n| `useUser` | 用户信息 + 拉取 | `const { userInfo, fetchUserInfo } = useUser()` |\n| `useAvatar` | 头像 | `const { avatarUrl } = useAvatar()` |\n| `getUserProfile` | API：获取用户信息 | `await getUserProfile()` |\n| `updateUserProfile` | API：更新用户信息 | `await updateUserProfile({ nickname })` |\n| `changePassword` | API：修改密码 | `await changePassword({ old, new })` |\n| `setPassword` | API：首次设置密码 | `await setPassword({ password })` |\n| `deactivateAccount` | API：注销账号 | `await deactivateAccount()` |\n| `unbindOAuth` | API：解绑 OAuth | `await unbindOAuth('github')` |\n\n### 评论\n\n| 函数 | 说明 | 示例 |\n|---|---|---|\n| `useComments` | 获取评论列表 | `const { comments, fetchComments } = useComments()` |\n| `fillComment` | 填充评论用户信息 | `fillComment(comment)` |\n| `flattenComments` | 将嵌套评论扁平化 | `flattenComments(comments)` |\n| `provideCommentContext` | 提供评论上下文 | `provideCommentContext(articleId)` |\n| `useCommentContext` | 获取评论上下文 | `const ctx = useCommentContext()` |\n| `getComments` | API：获取评论 | `await getComments({ target_type: 'article', target_key: 'slug' })` |\n| `createComment` | API：发表评论 | `await createComment({ target_type: 'article', target_key: 'slug', content: '...' })` |\n| `deleteComment` | API：删除评论 | `await deleteComment(id)` |\n\n### 主题与配置\n\n| 函数 | 说明 | 示例 |\n|---|---|---|\n| `useTheme` | 获取激活主题及其菜单 | `const { themeConfig, getMenus } = useTheme()` |\n| `useSysConfig` | 系统配置（标题/描述/OAuth） | `const { basicConfig, oauthConfig } = useSysConfig()` |\n| `getActiveTheme` | API：获取激活主题 | `await getActiveTheme()` |\n| `getSettingGroup` | API：获取配置组 | `await getSettingGroup('basic')` |\n\n### 暗色模式\n\n| 函数 | 说明 | 示例 |\n|---|---|---|\n| `useDarkMode` | 暗色模式控制 | `const { isDark, toggleTheme, initAutoSwitch } = useDarkMode()` |\n\n### 分类\n\n| 函数 | 说明 | 示例 |\n|---|---|---|\n| `useCategory` | 按 slug 获取分类 | `const { category } = useCategory(slug)` |\n| `useCategories` | 获取全部分类 | `const { categories } = useCategories()` |\n| `getCategories` | API：分类列表 | `await getCategories()` |\n| `getCategoryById` | API：按 ID 获取 | `await getCategoryById(1)` |\n| `getCategoryBySlug` | API：按 slug 获取 | `await getCategoryBySlug('frontend')` |\n\n### 标签\n\n| 函数 | 说明 | 示例 |\n|---|---|---|\n| `useTag` | 按 slug 获取标签 | `const { tag } = useTag(slug)` |\n| `useTags` | 获取全部标签 | `const { tags } = useTags()` |\n| `getTags` | API：标签列表 | `await getTags()` |\n| `getTagById` | API：按 ID 获取 | `await getTagById(1)` |\n| `getTagBySlug` | API：按 slug 获取 | `await getTagBySlug('vue')` |\n\n### 友链\n\n| 函数 | 说明 | 示例 |\n|---|---|---|\n| `useFriends` | 友链和友链分组 | `const { data: friendGroups, refresh } = useFriends()` |\n| `useFriendApply` | 提交友链申请 | `const { apply } = useFriendApply()` |\n| `getFriends` | API：友链列表 | `await getFriends()` |\n| `applyFriend` | API：申请友链 | `await applyFriend({ name, url, description, avatar })` |\n\n### 统计\n\n| 函数 | 说明 | 示例 |\n|---|---|---|\n| `useStats` | 站点统计 | `const { siteStats } = useStats()` |\n| `useArchives` | 归档统计 | `const { archives } = useArchives()` |\n| `getSiteStats` | API：站点统计 | `await getSiteStats()` |\n| `getArchiveStats` | API：归档统计 | `await getArchiveStats()` |\n\n### 动态\n\n| 函数 | 说明 | 示例 |\n|---|---|---|\n| `useMomentList` | 动态列表 | `const { data: moments } = useMomentList()` |\n| `getMoments` | API：动态列表 | `await getMoments()` |\n\n### 订阅\n\n| 函数 | 说明 | 示例 |\n|---|---|---|\n| `useSubscribe` | 邮箱订阅/退订 | `const { subscribe, unsubscribe } = useSubscribe()` |\n| `subscribe` | API：订阅 | `await subscribe({ email })` |\n| `unsubscribe` | API：退订 | `await unsubscribe({ email })` |\n\n### 通知\n\n| 函数 | 说明 | 示例 |\n|---|---|---|\n| `useNotifications` | 通知列表 + 未读数 | `const { unreadCount, notifications } = useNotifications()` |\n| `getNotifications` | API：通知列表 | `await getNotifications()` |\n| `markAsRead` | API：标记已读 | `await markAsRead(id)` |\n| `markAllAsRead` | API：全部已读 | `await markAllAsRead()` |\n\n### 反馈\n\n| 函数 | 说明 | 示例 |\n|---|---|---|\n| `useFeedback` | 提交反馈 | `const { submit } = useFeedback()` |\n| `submitFeedback` | API：提交反馈 | `await submitFeedback({ reportUrl, reportType: 'bug', description })` |\n| `getFeedbackByTicketNo` | API：按工单号查询 | `await getFeedbackByTicketNo('T2025...')` |\n\n### Markdown\n\n| 函数 | 说明 | 示例 |\n|---|---|---|\n| `renderMarkdown` | 完整渲染（代码高亮/Katex） | `const html = renderMarkdown(content)` |\n| `renderSimpleMarkdown` | 简单渲染（不含高亮） | `const html = renderSimpleMarkdown(content)` |\n| `extractToc` | 提取文章目录 | `const toc = extractToc(content)` |\n| `countWords` | 统计字数 | `countWords(content)` |\n| `estimateReadingTime` | 预估阅读时间（分钟） | `estimateReadingTime(content, 300)` |\n\n### 日期\n\n| 函数 | 说明 | 示例 |\n|---|---|---|\n| `formatDateTime` | `2025-10-03 13:46:59` | `formatDateTime(date)` |\n| `formatDate` | `2025-10-03` | `formatDate(date)` |\n| `formatRelativeTime` | `2小时前` | `formatRelativeTime(date)` |\n| `formatFriendly` | `2025年10月3日` | `formatFriendly(date)` |\n| `formatMomentTime` | `刚刚` / `3天前` / `10月3日` | `formatMomentTime(date)` |\n| `formatForBackend` | 转后端格式 | `formatForBackend(date)` |\n| `parseBackendDate` | 解析后端日期 | `parseBackendDate('2025-10-03 13:46:59')` |\n| `isValidDate` | 日期是否有效 | `isValidDate(date)` |\n\n### 表情\n\n| 函数 | 说明 | 示例 |\n|---|---|---|\n| `loadEmojiGroups` | 加载表情分组 | `const groups = await loadEmojiGroups(url)` |\n| `loadEmojiMap` | 加载 `:key:` → URL 映射 | `const map = await loadEmojiMap(url)` |\n| `replaceEmojisInText` | 替换文本中的表情占位符 | `replaceEmojisInText(text, map)` |\n\n### 滚动\n\n| 函数 | 说明 | 示例 |\n|---|---|---|\n| `scrollToTop` | 平滑回到顶部 | `scrollToTop()` |\n| `scrollToElement` | 滚动到指定元素 | `scrollToElement('#comments')` |\n\n### UI\n\n| 函数 | 说明 | 示例 |\n|---|---|---|\n| `useToast` | Toast 消息 | `const { success, error } = useToast()` |\n| `useExpandable` | 内容展开/收起 | `const { isExpanded, toggle } = useExpandable()` |\n\n### 上传\n\n| 函数 | 说明 | 示例 |\n|---|---|---|\n| `useUpload` | 上传文件 | `const { upload } = useUpload()` |\n| `uploadFile` | API：上传单文件 | `await uploadFile({ file })` |\n\n### 工具\n\n| 函数 | 说明 | 示例 |\n|---|---|---|\n| `parseJSON` | 安全解析 JSON | `parseJSON(str)` |\n| `createApi` | 创建 API 工厂实例 | `const api = createApi('/resource')` |\n| `apiRequest` | 通用请求（自动 token/Auth） | `await apiRequest('/path')` |\n\n## 类型\n\nTypeScript 类型需要显式 import。统一从 `@flecblog/core-nuxt` 导入，自动索引所有类型。\n\n```ts\nimport type { Article, ArticleQuery, ApiResponse, PaginationData, UserInfo, Comment } from '@flecblog/core-nuxt';\n```\n\n可用类型：\n\n| 模块 | 类型 |\n|---|---|\n| 文章 | `Article` `ArticleNav` `ArticleQuery` |\n| 认证 | `LoginParams` `LoginResponse` `RegisterParams` `RegisterResponse` `ForgotPasswordParams` `ResetPasswordParams` `RefreshTokenResponse` |\n| 分类 | `Category` |\n| 评论 | `Comment` `CreateCommentParams` `GetCommentsParams` `FlatComment` `EmojiItem` `EmojiGroup` `CommentTargetType` |\n| 反馈 | `Feedback` `SubmitFeedbackParams` `ReportType` `FeedbackStatus` |\n| 友链 | `Friend` `FriendGroup` `FriendGroupedResponse` `FriendApplyRequest` |\n| 动态 | `Moment` `MomentContent` `MomentMusic` `AudioTrack` `LyricLine` `MomentListResponse` |\n| 通知 | `Notification` `NotificationType` `GetNotificationsParams` |\n| 请求 | `ApiResponse<T>` `PaginationQuery` `PaginationData<T>` |\n| 统计 | `SiteStats` `ArchiveItem` `ArchiveStats` |\n| 配置 | `SysConfigData` `SettingGroupType` |\n| 标签 | `Tag` |\n| 主题 | `ThemeMenuItem` `ActiveTheme` |\n| 上传 | `UploadResponse` `UploadType` |\n| 用户 | `UserInfo` `UpdateProfileParams` `ChangePasswordParams` `UserRole` |\n| Markdown | `TocItem` |\n\n## 样式\n\n包提供 `base.css` 和 `prose.css`，会在 `extends` 时自动加载，可在主题中创建同名选择器覆盖。\n\n- **`base.css`**：CSS 重置、RemixIcon 字体图标\n- **`prose.css`**：文章内容完整排版（亮/暗双主题），包含标题、代码块、表格、引用、自定义卡片等 20+ 种元素样式\n\n## 许可证\n\nMIT\n","readmeFilename":"README.md"}