You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在使用Ant Design与next-with-less的Next.js项目中添加主题切换器?

Next.js + Ant Design + Less 亮暗主题切换实现方案

步骤1:调整 next.config.js 配置

新增less变量绑定配置,将Ant Design内置主题变量统一关联到CSS自定义属性,支持客户端动态切换:

const withLess = require("next-with-less");

module.exports = withLess({
  reactStrictMode: false,
  lessLoaderOptions: {
    lessOptions: {
      modifyVars: {
        // 绑定Ant Design变量到CSS自定义属性
        "primary-color": "var(--primary-color)",
        "link-color": "var(--link-color)",
        "success-color": "var(--success-color)",
        "warning-color": "var(--warning-color)",
        "error-color": "var(--error-color)",
        "font-size-base": "var(--font-size-base)",
        "heading-color": "var(--heading-color)",
        "text-color": "var(--text-color)",
        "text-color-secondary": "var(--text-color-secondary)",
        "disabled-color": "var(--disabled-color)",
        "border-radius-base": "var(--border-radius-base)",
        "border-color-base": "var(--border-color-base)",
        "box-shadow-base": "var(--box-shadow-base)",
        "body-background": "var(--body-background)",
        "component-background": "var(--component-background)",
      },
      javascriptEnabled: true,
    },
  },
});

步骤2:修改 global.less 新增暗色主题变量

保留原有亮色主题变量,新增暗色主题下的对应变量值:

@import "~antd/dist/antd.less";
@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@200;400;700&display=swap");

// 固定公共变量
@border-radius-base: 10px;
@font-size-base: 14px;

// 亮色主题变量
:root {
  --primary-color: #26695c;
  --light-primary-color: #e5edef;
  --link-color: #1890ff;
  --success-color: #52c41a;
  --warning-color: #faad14;
  --error-color: #f5222d;
  --heading-color: rgba(0, 0, 0, 0.85);
  --text-color: rgba(0, 0, 0, 0.65);
  --text-color-secondary: rgba(0, 0, 0, 0.45);
  --disabled-color: rgba(0, 0, 0, 0.25);
  --border-color-base: #d9d9d9;
  --box-shadow-base: 0 2px 8px rgba(0, 0, 0, 0.15);
  --body-background: #f3f5fa;
  --component-background: #ffffff;
  --shadow-base: var(--box-shadow-base);
}

// 暗色主题变量
html.dark {
  --primary-color: #4ca897;
  --light-primary-color: #1a3d36;
  --link-color: #40a9ff;
  --success-color: #73d13d;
  --warning-color: #ffc53d;
  --error-color: #ff4d4f;
  --heading-color: rgba(255, 255, 255, 0.85);
  --text-color: rgba(255, 255, 255, 0.65);
  --text-color-secondary: rgba(255, 255, 255, 0.45);
  --disabled-color: rgba(255, 255, 255, 0.25);
  --border-color-base: #434343;
  --box-shadow-base: 0 2px 8px rgba(0, 0, 0, 0.45);
  --body-background: #121212;
  --component-background: #1e1e1e;
  --shadow-base: var(--box-shadow-base);
}

html,
body {
  font-family: "Poppins", sans-serif;
  background: var(--body-background);
  transition: background 0.3s ease;
}

#__next {
  height: 100%;
}

.ant-btn {
  display: flex;
  align-items: center;
}
.ant-btn span {
  margin-left: 5px;
  margin-right: 5px;
}
.ant-card .ant-card-cover {
  width: 100%;
}

步骤3:实现主题状态全局管理

新建contexts/ThemeContext.js文件实现状态持久化与切换逻辑:

import { createContext, useContext, useEffect, useState } from 'react';

const ThemeContext = createContext();

export function ThemeProvider({ children }) {
  const [theme, setTheme] = useState('light');

  // 初始化读取本地存储或系统主题偏好
  useEffect(() => {
    const savedTheme = localStorage.getItem('theme');
    const preferDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
    const initTheme = savedTheme || (preferDark ? 'dark' : 'light');
    setTheme(initTheme);
    document.documentElement.classList.toggle('dark', initTheme === 'dark');
  }, []);

  // 切换主题方法
  const toggleTheme = () => {
    const newTheme = theme === 'light' ? 'dark' : 'light';
    setTheme(newTheme);
    localStorage.setItem('theme', newTheme);
    document.documentElement.classList.toggle('dark', newTheme === 'dark');
  };

  return (
    <ThemeContext.Provider value={{ theme, toggleTheme }}>
      {children}
    </ThemeContext.Provider>
  );
}

export function useTheme() {
  return useContext(ThemeContext);
}

修改_app.js全局包裹主题Provider:

import { ThemeProvider } from '../contexts/ThemeContext';
import '../styles/global.less';

function MyApp({ Component, pageProps }) {
  return (
    <ThemeProvider>
      <Component {...pageProps} />
    </ThemeProvider>
  );
}

export default MyApp;

步骤4:添加主题切换按钮

在仪表板导航栏对应位置插入切换按钮即可:

import { Button } from 'antd';
import { SunOutlined, MoonOutlined } from '@ant-design/icons';
import { useTheme } from '../contexts/ThemeContext';

export default function ThemeToggleButton() {
  const { theme, toggleTheme } = useTheme();

  return (
    <Button
      type="text"
      icon={theme === 'light' ? <MoonOutlined /> : <SunOutlined />}
      onClick={toggleTheme}
    >
      {theme === 'light' ? '切换暗色' : '切换亮色'}
    </Button>
  );
}

内容的提问来源于stack exchange,提问作者Musawer Shah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 21:54:03