主页 > 手机  > 

nextjs+materialUI实现换肤功能

nextjs+materialUI实现换肤功能
一、搭建nextjs开发环境 1、创建一个命名为nextjs-mui-theme的项目 pnpm dlx create-next-app@14.2.16 nextjs-mui-theme

注释:这是使用的是nextjs的14.2.16版本 

 2、安装material-ui依赖 pnpm add @mui/material @emotion/react @emotion/styled

 material-ui官网

3、安装Roboto font和nextjs兼容mui所需的依赖 pnpm add @fontsource/roboto pnpm add @mui/material-nextjs @emotion/cache

安装完毕后,在layout布局页面引入字体,以及引入这个依赖:

import '@fontsource/roboto/300.css'; import '@fontsource/roboto/400.css'; import '@fontsource/roboto/500.css'; import '@fontsource/roboto/700.css'; import { AppRouterCacheProvider } from '@mui/material-nextjs/v15-appRouter'; import type { Metadata } from 'next'; import './globals.css'; export const metadata: Metadata = { title: 'Create Next App', description: 'Generated by create next app' }; export default function RootLayout({ children }: Readonly<{ children: React.ReactNode; }>) { return ( <html lang="en" suppressContentEditableWarning> <body> {/* 调用我们自己的css层,因此这选择关闭 */} <AppRouterCacheProvider>{children}</AppRouterCacheProvider> </body> </html> ); }

 在 HTML 或 React 中,suppressContentEditableWarning 属性的作用是 抑制内容可编辑元素 (contentEditable) 的警告。

4、安装material icon pnpm add @mui/icons-material

然后在globals.css当中引入material icon的样式:

@import url( fonts.googleapis /icon?family=Material+Icons); @tailwind base; @tailwind components; @tailwind utilities; * { box-sizing: border-box; padding: 0; margin: 0; } html, body { max-width: 100vw; overflow-x: hidden; } .myBg { color: var(--mui-palette-common-background); } @layer utilities { .text-balance { text-wrap: balance; } }

注意@import url( fonts.googleapis /icon?family=Material+Icons);引入要放到tailwindcss上面,否则会爆出错误

二、自定义material主题

1、创建主题文件

在src目录下创建上下文context目录,在该目录下创建一个AppThemeContext.tsx文件,代码如下:

'use client'; import { createTheme, CssBaseline, responsiveFontSizes } from '@mui/material'; import { ThemeProvider } from '@mui/material/styles'; import type {} from '@mui/material/themeCssVarsAugmentation'; import { createContext, useContext, useMemo } from 'react'; export const AppThemeContext = createContext(null); const AppThemeProvider = ({ children }: Readonly<{ children: React.ReactNode; }>) => { const theme = useMemo(() => { return responsiveFontSizes( createTheme({ // 使用CSS变量的有点,防止暗黑模式SS、闪烁 cssVariables: { colorSchemeSelector: 'class', disableCssColorScheme: true }, palette: { mode: 'light', primary: { main: 'rgb(10, 18, 42)', contrastText: 'rgb(255, 255, 255)' }, secondary: { main: 'rgb(27, 59, 111)', contrastText: 'rgb(255, 255, 255)' } }, // 在这里你可以定义不同的颜色方案 colorSchemes: { // 这是亮色的配置设置 light: { palette: { mode: 'light', primary: { main: 'rgb(10, 18, 42)' }, secondary: { main: 'rgb(27, 59, 111)' } } }, // 这是深色的配置设置 dark: { palette: { mode: 'dark', primary: { main: 'rgb(10, 18, 42)' }, secondary: { main: 'rgb(27, 59, 111)' } } } } }) ); }, []); return ( <AppThemeContext.Provider value={null}> {/* defaultMode默认是system,可选项有system、light、dark ;disableTransitionOnChange禁用切换动画*/} <ThemeProvider defaultMode="dark" theme={theme} disableTransitionOnChange> {/*在所有设备上, 启用颜色方案 */} <CssBaseline enableColorScheme /> {children} </ThemeProvider> </AppThemeContext.Provider> ); }; export const useAppThemeContext = () => useContext(AppThemeContext); export default AppThemeProvider;

然后引入到layout布局组件当中:

import AppThemeProvider from '@/context/AppThemeContext'; import '@fontsource/roboto/300.css'; import '@fontsource/roboto/400.css'; import '@fontsource/roboto/500.css'; import '@fontsource/roboto/700.css'; import { AppRouterCacheProvider } from '@mui/material-nextjs/v15-appRouter'; import InitColorSchemeScript from '@mui/material/InitColorSchemeScript'; import type { Metadata } from 'next'; import './globals.css'; export const metadata: Metadata = { title: 'Create Next App', description: 'Generated by create next app' }; export default function RootLayout({ children }: Readonly<{ children: React.ReactNode; }>) { return ( <html lang="en" suppressContentEditableWarning> <body> {/* 调用我们自己的css层,因此这选择关闭 */} <AppRouterCacheProvider options={{ enableCssLayer: false }}> <AppThemeProvider> <InitColorSchemeScript defaultMode="dark" attribute="class" /> {children} </AppThemeProvider> </AppRouterCacheProvider> </body> </html> ); }

 2、创建切换主题按钮

在src下创建components文件夹,定一个ToggleModeColor.tsx组件:

'use client'; import DarkModeOutlinedIcon from '@mui/icons-material/DarkModeOutlined'; import LightModeOutlinedIcon from '@mui/icons-material/LightModeOutlined'; import { Box, IconButton } from '@mui/material'; import { useColorScheme } from '@mui/material/styles'; import { useCallback } from 'react'; const ToggleModeColor = () => { const { mode, setMode } = useColorScheme(); const toggleDarkMode = useCallback(() => { if (mode) { const currMode = mode === 'light' ? 'dark' : 'light'; setMode(currMode); } }, [mode, setMode]); return ( <Box sx={{ flexGrow: 0, pr: 2 }}> <IconButton size="large" aria-label="account of current user" aria-controls="menu-appbar" aria-haspopup="true" onClick={toggleDarkMode} color="inherit" > {mode === 'dark' ? <DarkModeOutlinedIcon /> : <LightModeOutlinedIcon />} </IconButton> </Box> ); }; export default ToggleModeColor;

三、重启运行

 

标签:

nextjs+materialUI实现换肤功能由讯客互联手机栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“nextjs+materialUI实现换肤功能