Skip to content

自定义主题

沈孟平
最后更新于 2025-01-13 13:50:11

提示

  1. 如果要将你的主题配置为默认主题,此时你的配置文件也就是 xxx.json 文件里的,layout.CUR_THEME 需要设置为你的主题名称。
  2. 自定义 css 可以是 css 字符串,也可以是一个相对路径引入 css 文件,比如 ./gupo-custom.css

本模板提供了灵活的主题定制功能,允许您根据需求自定义界面风格。主题配置文件位于 src/theme/config/ 目录下,包括:

  • default.json: Naive UI 默认主题
  • antd.json: 仿 Ant Design 风格主题
  • gupo.json: 古珀主题
  • nuxt.json: 仿 Nuxt UI 风格主题
  • playground.ts: 用于调试主题文件,支持类型提示,方便调试

每一个配置文件可以包含如下内容:

  • 亮色主题
  • 暗色主题
  • 布局配置(可选)
  • 全局样式(可选)
json
{
  // 布局配置
  "layout": {
    "CUR_THEME": "antd"
  },
  // 亮色主题
  "light": {
    "common": {
      "primaryColor": "#1677ff"
    }
  },
  // 暗色主题
  "dark": {
    "common": {
      "primaryColor": "#1677ff"
    },
    // 单个组件自定义
    "Button": {}
  },
  // 全局样式,用来覆盖 Naive UI 组件样式,如果不是后端加载主题,你也可以写成 './gupo-custom.css' 这种形式,以便于本地修改。具体参考 `gupo.json` 文件
  "css": ".n-tree-node--selected .n-tree-node-content { color: var(--primary-color); } .n-tree:not(.n-tree--block-line) .n-tree-node:not(.n-tree-node--disabled).n-tree-node--pending:not(.n-tree-node--selected)>.n-tree-node-content:not(:hover) { background: transparent; }"
}

配置主题

如果需要获取 json 配置文件,有两种方式:

  1. 可以通过 naive 文档 上的主题配置按钮进行操作。如果配置的是暗色,则先将 naive 文档主题切换为暗色,然后进行配置,配置完后导出放到 json 下的 dark 配置项中。亮色类似操作,此处不再赘述。
  2. 可以使用 playground.ts 文件,支持类型提示,方便调试,调试结束后 console.log 输出为 json 后,创建属于你自己的主题即可。(推荐)

新增主题

src/theme/config/ 目录下新增一个主题配置文件,然后修改 src/theme/config/index.ts 文件,此处以添加一个接口请求来的主题为例,本地主题请看文件下的其他配置。 user_name

ts
import type { GlobalThemeOverrides } from 'naive-ui'

export interface ThemeContent {
  dark?: GlobalThemeOverrides
  light: GlobalThemeOverrides
  css?: string
  layout?: Recordable
}

export type ThemeMap = Record<string, () => Promise<ThemeContent>>

export const THEME_MAP: ThemeMap = {
  default: () => import('./default.json').then(module => module),
  antd: () => import('./antd.json').then(module => module),
  custom: () => import('./custom.json').then(module => module),
  // 后端主题
  backendTheme: () => BACKEND_API.getTheme().then(res => res.data.data), 
}

export const themeOptions = [
  { label: 'default', value: 'default' },
  { label: 'antd', value: 'antd' },
  { label: 'custom', value: 'custom' },
  // 后端主题
  { label: 'backendTheme', value: 'backendTheme' }, 
]

export async function loadTheme(themeName: string) {
  const themeContent = await THEME_MAP[themeName]()
  if (themeContent.css) {
    const styleElement = document.createElement('style')
    styleElement.textContent = themeContent.css
    document.head.appendChild(styleElement)
  }
  return themeContent
}

Last updated: