Nuxt3 服务端渲染 、elementplus多皮肤黑暗模式

在上一节基础上,接下来我们来引入我们开发所需要的UI组件elementplus,实现顶部和底部整体布局以及配置黑暗模式 。最终效果如下:

Nuxt3 服务端渲染 、elementplus多皮肤黑暗模式_第1张图片

基础模式

Nuxt3 服务端渲染 、elementplus多皮肤黑暗模式_第2张图片 

黑暗模式

一、引入组件


//安装elementplus
1、npm install element-plus --save

//安装 @element-plus/icons 图标库
2、npm install  @element-plus/icons

 二、然后在我们的plugins创建element-plus.client.ts文件。注意:如果我们在文件命名时加上 .client,例如 element-plus.client.ts,此时代表该插件只在客户端加载


import *  as ElementPlus from 'element-plus/dist/index.full'
import zhCn from 'element-plus/es/locale/lang/zh-cn'
// @ts-ignore
import { defineNuxtPlugin } from '#app'

export default defineNuxtPlugin(nuxtApp => {
  nuxtApp.vueApp.use(ElementPlus, {
    locale: zhCn,
  })
})

找到nuxt.config.ts,引入样式:


  css:[
        'element-plus/dist/index.css',
        '~/assets/css/resetElStyle.scss'
    ],

三、找到我们的整体布局组件default.vue,我们来使用一下引入的elementplus,看是否引入成功。(我做了一个简单布局,使用了scss,所以复制的时候需要大家提前安装一下scss)

在顶部引入一个模式切换组件。如图:

Nuxt3 服务端渲染 、elementplus多皮肤黑暗模式_第3张图片新增模式切换功能

1、首先我们引入图标及切换组件:


//引入我们需要的图标
import { Moon, Sunny,  Search} from '@element-plus/icons-vue'
//引入样式文件
import theme from '@/utils/theme'
import { colorMix } from "@/utils/tool"

//在页面使用

    
// 设置switch的背景颜色
const blackColor = 'var(--bg-color-mute)'
const themeColorObj = {
  defaultTheme: {
    title: '浅色主题'
  },
  darkTheme: {
    title: '深色主题'
  }
}

//模式切换事件

const themeChange = (val: boolean) => {
  if(val){
    state.currentSkinName = 'defaultTheme'
    switchTheme( state.currentSkinName )
  }else{
    state.currentSkinName = 'darkTheme'
    switchTheme(state.currentSkinName)
  }
}
const switchTheme = (type?:string) =>{
  type = type || 'darkTheme'
  const colorObj = theme[type]
  for (let i = 1; i < 10; i += 1) {
    colorObj[`--el-color-primary-light-${10 - i}`] = colorMix(colorObj['--el-color-white'], colorObj['--el-color-primary'], i * 0.1)
  }
  Object.keys(colorObj).map(item => {
    document.documentElement.style.setProperty(item, colorObj[item])
  })
}

2、事件处理完毕,接下来我们就需要配置主题的样式

首先:在utils创建样式文件theme.ts及tool.ts,我们只处理两种模式,如果要多种可自行拓展,完整代码如下:可以直接拷贝到自己项目中

theme.ts

export default {
  'defaultTheme': {
    '--el-background-color-base': '#ffffff',
    '--el-color-white': '#ffffff',
    '--el-text-color-bar':'#ffffff',
    '--el-color-black': '#ffffff',
    '--el-color-primary': '#409eff',
    '--el-navbar_bg':'#0440D7',//导航
    '--el-slider_bg':'#0440D7',
    '--el-background-top-color':'#e3e4e5',
    "--el-box-color-base": "#f5f7fa", // 分类框
    '--el-logo_bg':'#333',//logo
    '--el-en_bg':'#666666',//英文
    '--bg-color-mute': '#f2f2f2',//模式切换按钮
    '--el-text-color-cls': '#666666',//顶部选项颜色
    '--el-text-color-th': 'rgba(0, 0, 0, 0.3)', // 最次要文字颜色
    '--el-color-primary-light-1': '#53a8ff',
    '--el-color-primary-light-2': '#66b1ff',
    '--el-color-primary-light-3': '#79bbff',
    '--el-color-primary-light-4': '#8cc5ff',
    '--el-color-primary-light-5': '#a0cfff',
    '--el-color-primary-light-6': '#b3d8ff',
    '--el-color-primary-light-7': '#c6e2ff',
    '--el-color-primary-light-8': '#d9ecff',
    '--el-color-primary-light-9': '#ecf5ff',
    '--el-input-bg-color': '#fff', //输入框背景色
    '--el-fill-color-blank': '#fff',
    '--el-select-box':'#fff',//下拉框BG
    '--el-select-box-active':'#fff',//下拉框激活BG
    '--el-input-border-color':'#00adff',//下拉边框
    '--el-hover-bg-color':'#2590F9',//鼠标放入背景色
    '--el-switch_bg':'#f2f2f2', //模式切换
    '--el-switch-color':'#666666',//模式颜色
    '--el-footer-bg':'#F6F7F8',//底部颜色
    '--el-btn-color':'#ffffff',//按钮颜色

    '--el-color-success': '#67c23a',
    '--el-color-success-light': '#e1f3d8',
    '--el-color-success-lighter': '#f0f9eb',
    '--el-color-warning': '#e6a23c',
    '--el-color-warning-light': '#faecd8',
    '--el-color-warning-lighter': '#fdf6ec',
    '--el-color-danger': '#f56c6c',
    '--el-color-danger-light': '#fde2e2',
    '--el-color-danger-lighter': '#fef0f0',
    '--el-color-error': '#f56c6c',
    '--el-color-error-light': '#fde2e2',
    '--el-color-error-lighter': '#fef0f0',
    '--el-color-info': '#909399',
    '--el-color-info-light': '#e9e9eb',
    '--el-color-info-lighter': '#f4f4f5',
    '--el-text-color-primary': '#303133',
    '--el-text-color-regular': '#606266',
    '--el-text-color-secondary': '#909399',
    '--el-text-color-placeholder': '#c0c4cc',
    '--el-border-color-base': '#dcdfe6',
    '--el-border-color-light': '#e4e7ed',
    '--el-border-color-lighter': '#ebeef5',
    '--el-border-color-extra-light': '#f2f6fc',
    '--color-input-bg': '#f4f5f5',
    '--color-input-error-bg': '#ffece8',
    '--color-input-placeholder': '#86909c',
    '--color-input-text': '#4e5969',
    '--color-input-icon': '#f53f3f',
    '--el-popup-modal-background-color': 'var(--el-color-black)',
    '--el-popup-modal-opacity': '.5',
    '--el-border-width-base': '1px',
    '--el-border-style-base': 'solid',
    '--el-border-color-hover': 'var(--el-text-color-placeholder)',
    '--el-border-base': 'var(--el-border-width-base) var(--el-border-style-base) var(--el-border-color-base)',
    '--el-border-radius-base': '4px',
    '--el-border-radius-small': '2px',
    '--el-border-radius-round': '20px',
    '--el-border-radius-circle': '100%',
    '--el-box-shadow-base': '0 2px 4px rgba(0, 0, 0, .12),0 0 6px rgba(0, 0, 0, .04)',
    '--el-box-shadow-light': '0 2px 12px 0 rgba(0, 0, 0, .1)',
    '--el-svg-monochrome-grey': '#dcdde0',
    '--el-fill-base': 'var(--el-color-white)',
    '--el-font-size-extra-large': '20px',
    '--el-font-size-large': '18px',
    '--el-font-size-medium': '16px',
    '--el-font-size-base': '14px',
    '--el-font-size-small': '13px',
    '--el-font-size-extra-small': '12px',
    '--el-font-weight-primary': '500',
    '--el-font-line-height-primary': '24px',
    '--el-font-color-disabled-base': '#bbb',
    '--el-index-normal': '1',
    '--el-index-top': '1000',
    '--el-index-popper': '2000',
    '--el-disabled-fill-base': 'var(--el-background-color-base)',
    '--el-disabled-color-base': 'var(--el-text-color-placeholder)',
    '--el-disabled-border-base': 'var(--el-border-color-light)',
    '--el-transition-duration': '.3s',
    '--el-transition-duration-fast': '.2s',
    '--el-transition-function-ease-in-out-bezier': 'cubic-bezier(.645, .045, .355, 1)',
    '--el-transition-function-fast-bezier': 'cubic-bezier(.23, 1, .32, 1)',
    '--el-transition-all': 'all var(--el-transition-duration) var(--el-transition-function-ease-in-out-bezier)',
    '--el-transition-fade': 'opacity var(--el-transition-duration) var(--el-transition-function-fast-bezier)',
    '--el-transition-md-fade': 'transform var(--el-transition-duration) var(--el-transition-function-fast-bezier),opacity var(--el-transition-duration) var(--el-transition-function-fast-bezier)',
    '--el-transition-fade-linear': 'opacity var(--el-transition-duration-fast) linear',
    '--el-transition-border': 'border-color var(--el-transition-duration-fast) var(--el-transition-function-ease-in-out-bezier)',
    '--el-transition-color': 'color var(--el-transition-duration-fast) var(--el-transition-function-ease-in-out-bezier)'
  },
  'darkTheme':{
    "--el-color-primary": "#409eff", // 主题色
    '--el-background-top-color':'#262727',
    "--el-box-color-base": "#262727", // 分类框
    "--el-background-color-base": "#14161a", // 基础背景色
    "--el-color-white": "#1d1e1f", // 基础白色
    "--el-color-black": "#262727", // 基础黑色
    '--el-navbar_bg':'#14161a', //导航色
    '--el-switch_bg':'#2c2c2c', //模式切换
    '--el-logo_bg':'#fff',//logo
    '--el-slider_bg':'#1B222C',
    '--el-en_bg':'#fff',//英文
    '--el-btn-color':'#E5EAF3',//按钮颜色
    '--el-text-color-bar':'#ffffff',
    '--el-text-color-primary': '#FAFAFA', // 主要文字颜色
    '--el-text-color-regular': '#FAFAFA', // 常规文字颜色
    '--el-text-color-placeholder': '#c0c4cc',  // 占位文字颜色
    '--el-text-color-secondary': 'rgba(255, 255, 255, 0.5)', // 次要文字颜色
    '--el-text-color-th': 'rgba(255, 255, 255, 0.3)', // 最次要文字颜色
    '--el-text-color-cls': '#fff',//顶部选项颜色
    "--el-border-color-base": "#4C4D4F", // 一级边框颜色
    "--el-border-color-light": "#414243", // 二级边框颜色
    "--el-border-color-lighter": "#363637", // 三级边框颜色
    "--el-border-color-extra-light": "#2B2B2C", // 四级边框颜色
    '--el-input-bg-color': '#2c2c2c', //输入框背景色
    '--el-fill-color-blank': '#414243',
    '--el-select-box':'#4C4D4F',//下拉框BG
    '--el-select-box-active':'#414243',//下拉框激活BG
    '--el-input-border-color':'#fff',//下拉边框
    '--el-switch-color':'#ffffff',//模式颜色
    '--el-footer-bg':'rgba(255, 255, 255, 0.02)',//底部颜色
    '--bg-color-mute': '#2c2c2c',//模式切换按钮
    '--el-hover-bg-color':'#2590F9',//鼠标放入背景色
    '--el-color-success': '#67c23a', // 成功颜色
    '--el-color-success-light': '#e1f3d8',
    '--el-color-success-lighter': '#f0f9eb',
    '--el-color-warning': '#e6a23c', // 警告颜色
    '--el-color-warning-light': '#faecd8',
    '--el-color-warning-lighter': '#fdf6ec',
    '--el-color-danger': '#f56c6c', // 危险颜色
    '--el-color-danger-light': '#fde2e2',
    '--el-color-danger-lighter': '#fef0f0',
    '--el-color-error': '#f56c6c', // 错误颜色
    '--el-color-error-light': '#fde2e2',
    '--el-color-error-lighter': '#fef0f0',
    "--el-color-info": "#7B88A9", // 信息颜色
    '--el-color-info-light': '#e9e9eb',
    '--el-color-info-lighter': '#f4f4f5',
    '--color-input-bg': '#f4f5f5', // input 输入框
    '--color-input-error-bg': '#ffece8',
    '--color-input-placeholder': '#86909c',
    '--color-input-text': '#4e5969',
    '--color-input-icon': '#f53f3f',
    '--el-svg-monochrome-grey': '#dcdde0',
    '--el-font-color-disabled-base': '#bbb',
    '--el-popup-modal-background-color': 'var(--el-color-black)',
    '--el-popup-modal-opacity': '.5',
    '--el-border-width-base': '1px',
    '--el-border-style-base': 'solid',
    '--el-border-color-hover': 'var(--el-text-color-placeholder)',
    '--el-border-base': 'var(--el-border-width-base) var(--el-border-style-base) var(--el-border-color-base)',
    '--el-border-radius-base': '4px',
    '--el-border-radius-small': '2px',
    '--el-border-radius-round': '20px',
    '--el-border-radius-circle': '100%',
    '--el-box-shadow-base': '0 2px 4px rgba(0, 0, 0, .12),0 0 6px rgba(0, 0, 0, .04)',
    '--el-box-shadow-light': '0 2px 12px 0 rgba(0, 0, 0, .1)',
    '--el-fill-base': 'var(--el-color-white)',
    '--el-font-size-extra-large': '20px',
    '--el-font-size-large': '18px',
    '--el-font-size-medium': '16px',
    '--el-font-size-base': '14px',
    '--el-font-size-small': '13px',
    '--el-font-size-extra-small': '12px',
    '--el-font-weight-primary': '500',
    '--el-font-line-height-primary': '24px',
    '--el-index-normal': '1',
    '--el-index-top': '1000',
    '--el-index-popper': '2000',
    '--el-disabled-fill-base': 'var(--el-background-color-base)',
    '--el-disabled-color-base': 'var(--el-text-color-placeholder)',
    '--el-disabled-border-base': 'var(--el-border-color-light)',
    '--el-transition-duration': '.3s',
    '--el-transition-duration-fast': '.2s',
    '--el-transition-function-ease-in-out-bezier': 'cubic-bezier(.645, .045, .355, 1)',
    '--el-transition-function-fast-bezier': 'cubic-bezier(.23, 1, .32, 1)',
    '--el-transition-all': 'all var(--el-transition-duration) var(--el-transition-function-ease-in-out-bezier)',
    '--el-transition-fade': 'opacity var(--el-transition-duration) var(--el-transition-function-fast-bezier)',
    '--el-transition-md-fade': 'transform var(--el-transition-duration) var(--el-transition-function-fast-bezier),opacity var(--el-transition-duration) var(--el-transition-function-fast-bezier)',
    '--el-transition-fade-linear': 'opacity var(--el-transition-duration-fast) linear',
    '--el-transition-border': 'border-color var(--el-transition-duration-fast) var(--el-transition-function-ease-in-out-bezier)',
    '--el-transition-color': 'color var(--el-transition-duration-fast) var(--el-transition-function-ease-in-out-bezier)'
  }

}

tool.ts


export const colorMix = (color1, color2, weight) => {
  weight = Math.max(Math.min(Number(weight), 1), 0)
  let r1 = parseInt(color1.substring(1, 3), 16)
  let g1 = parseInt(color1.substring(3, 5), 16)
  let b1 = parseInt(color1.substring(5, 7), 16)
  let r2 = parseInt(color2.substring(1, 3), 16)
  let g2 = parseInt(color2.substring(3, 5), 16)
  let b2 = parseInt(color2.substring(5, 7), 16)
  let r: number | string = Math.round(r1 * (1 - weight) + r2 * weight)
  let g: number | string = Math.round(g1 * (1 - weight) + g2 * weight)
  let b: number | string = Math.round(b1 * (1 - weight) + b2 * weight)
  r = ("0" + (r || 0).toString(16)).slice(-2)
  g = ("0" + (g || 0).toString(16)).slice(-2)
  b = ("0" + (b || 0).toString(16)).slice(-2)
  return "#" + r + g + b;
}

最后我们来简单配置一下公共样式和模式切换重置公共样式:在assets/css 创建 resetElStyle.scss


.mt10 {
  margin-top: 10px;
}
body{
  background: var(--el-color-black)
}
.main_color{
  background-color: var(--el-background-color-base);
}
.el_base_color{
  background-color: var(--el-background-top-color);
}
.el-menu-item{
  border-bottom:none !important;
}
.right-menu .right-menu-item{
  width:62px;
  height:62px;
  background-color: var(--el-slider_bg);
  border-radius: 6px;
  overflow: hidden;
}
.right-menu-item .right-menu-qrcode .qrcode-box{
  background:var(--el-slider_bg);
  padding:5px
}
.right-menu-item .right-menu-qrcode p{
  padding:-12px 0 5px 0;
  text-align:center;
  color:#fff;
  font-size:12px
}
.logoWall .logo_animate{
  width: 100%;
  height: 450px;
  background: var(--el-background-color-base);
  position: relative;
}
body {
  p{
    color:var(--el-text-color-primary)
  }
  span{
    color:var(--el-text-color-primary)
  }
  .change_ico{
    margin-left:22px;
    width:42px;
    height:24px;
  }
  .change_ico  .el-switch__action{
    background-color: var(--el-switch-color) !important;
  }
  .change_ico .el-icon{
    font-size: 16px;
    color:var(--el-switch-color) !important;
  }
  //下拉框
  .el-scrollbar{
    background: var( --el-select-box);
    .selected{
      background: var(--el-select-box-active);
      color: var(--el-color-primary);
    }
    .el-select-dropdown__item.hover, .el-select-dropdown__item:hover{
      background: var(--el-select-box-active);
      color: var(--el-color-primary);
    }
  }
  /*数字输入框*/
  .el-input-number__decrease, .el-input-number__increase {
    background: var(--el-color-black)
  }

  // 复合输入框
  .el-input-group__append, .el-input-group__prepend {
    border: 1px solid var(--el-border-color-base);
    border-right: none;
  }

  //  日期选择 el-date-picker
  .el-picker-panel {
    border: 1px solid var(--el-border-color-light);
    background: var(--el-color-black)
  }


  // 日期和时间范围
  .el-date-editor .el-range-input {
    background: var(--el-color-white)
  }

  .el-picker-panel__footer {
    background: var(--el-color-black)
  }

  // 时间选择
  .el-time-panel__content {
    .el-time-spinner__item:hover, .el-scrollbar__thumb:hover {
      background: var(--el-select-box-active)
    }
  }

  // 表格分页
  .el-pagination.is-background .btn-next, .el-pagination.is-background .btn-prev, .el-pagination.is-background .el-pager li {
    background: var(--el-color-black)
  }

  // menu
  .el-menu {
    border-right: none;
  }
}

到此为止我们已经处理完毕,如果要在某个地方使用如下:例如


background-color: var(--el-background-color-base);
color: var(--el-color-primary);

⚠️注:原文首发至个人头条号  “  胖奶奶与胖小伙  ”

你可能感兴趣的:(nuxt3,javascript,开发语言,elementui,vue.js,前端框架)