element UI


文档:https://element-plus.org/zh-CN/guide/design.html
开箱即用:
https://github.com/youlaitech/vue3-element-admin-thin

npm create vite@latest element_demo -- --template vue-ts 创建一个vue模板项目
cd element_demo 或在IDE中直接打开文件
npm install element-plus --save
npm install

升级:

sh
npm i -D unplugin-auto-import unplugin-vue-components unplugin-element-plus  # 升级自动导入相关插件  # 中文注释
npm i @element-plus/icons-vue@latest -S  # 升级图标包  # 中文注释
npm i element-plus@latest -S             # 升级组件库本体  # 中文注释

编辑main.ts:

ts
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import zhCn from 'element-plus/es/locale/lang/zh-cn' // 中文
import 'element-plus/dist/index.css' //导入element样式
import 'element-plus/theme-chalk/dark/css-vars.css' //导入element黑暗样式
import './style.css' //导入自定义样式
import App from './App.vue'

const app = createApp(App)
app.use(ElementPlus, { size: 'small', zIndex: 3000 ,locale: zhCn}) // 全局引入

全局允许tailwind穿透class样式
编辑tstyle.css:

json
@import "tailwindcss" important; //添加important

响应式布局

屏幕代码
xs <768px
sm ≥768px *
md ≥992px *推荐以此以上作为桌面端
lg ≥1200px *
xl ≥1920px

隐藏
hidden-xs-only - 当视口在 xs 尺寸时隐藏
hidden-sm-only - 当视口在 sm 尺寸时隐藏 *
hidden-sm-and-down - 当视口在 sm 及以下尺寸时隐藏
hidden-sm-and-up - 当视口在 sm 及以上尺寸时隐藏
hidden-md-only - 当视口在 md 尺寸时隐藏
hidden-md-and-down - 当视口在 md 及以下尺寸时隐藏
hidden-md-and-up - 当视口在 md 及以上尺寸时隐藏
hidden-lg-only - 当视口在 lg 尺寸时隐藏
hidden-lg-and-down - 当视口在 lg 及以下尺寸时隐藏
hidden-lg-and-up - 当视口在 lg 及以上尺寸时隐藏
hidden-xl-only - 当视口在 xl 尺寸时隐藏

栅格换行
以一个屏幕宽度以24栅格为单位,12格就是一半屏幕

html
<!-- 行容器 -->
<el-row>
	<!-- 列容器 md屏幕以上一半屏幕 xs可改为sm或不设置-->
    <el-col :xs="24" :md="12">
	</el-col>
	<el-col :xs="24" :md="12">
	</el-col>
</el-row>

组件功能

消息闪现

ts
import { ElMessage } from 'element-plus'
// 假设这是某函数中:
ElMessage.success('成功,绿色')
ElMessage.warning('警告,黄色')
ElMessage.error('遇到错误,红色警告')

tailwindcss 覆盖element组件默认样式

例如element两个按钮会默认添加一个间距的参数,此时就可以替换它
[&_<浏览器中的元素类名>]:<被替换的tailwind样式>

自定义主题+黑暗模式切换

创建存储桶和使用pinia文件storage.ts:

ts
/**
 * - 状态持久化到 localStorage
 * - 首次初始化时,若无偏好则跟随系统
 */
import { defineStore } from 'pinia'

export type Theme = 'light' | 'dark'

export const useThemeStore = defineStore('theme', {
  state: () => ({
    theme: 'light' as Theme
  }),

  actions: {
    /** 初始化主题(读取本地或跟随系统) */
    initThemeStore() {
      const saved = localStorage.getItem('theme') as Theme | null
      if (saved === 'light' || saved === 'dark') {
        this.theme = saved
      } else if (typeof window !== 'undefined') {
        this.theme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
        localStorage.setItem('theme', this.theme)
      }
    },

    /** 设置主题并持久化 */
    setTheme(theme: Theme) {
      this.theme = theme
      localStorage.setItem('theme', theme)
    }
  }
})

创建切换主题文件useTheme.ts:

ts
/**
 * - 负责把主题写到 DOM(切换 html.dark)
 * - 对外暴露 theme、toggleTheme 和 getThemeLabel
 */
import { computed, onMounted } from 'vue'
import { useThemeStore } from './storage'

export type Theme = 'light' | 'dark'

export function useTheme() {
  const store = useThemeStore()
  const theme = computed(() => store.theme)

  /** 应用主题到 DOM:加/删 html.dark */
  const applyTheme = (t: Theme) => {
    const html = document.documentElement
    t === 'dark' ? html.classList.add('dark') : html.classList.remove('dark')
  }

  /** 切换主题 */
  const toggleTheme = () => {
    const next = theme.value === 'light' ? 'dark' : 'light'
    store.setTheme(next)
    applyTheme(next)
  }

  /** 文案 */
  const getThemeLabel = (t: Theme) => (t === 'light' ? '明亮模式' : '黑暗模式')

  // 首次挂载时初始化 + 应用
  onMounted(() => {
    store.initThemeStore()
    applyTheme(theme.value)
  })

  return { theme, toggleTheme, getThemeLabel }
}

main.ts(确保引入暗色变量文件)

ts
import 'element-plus/dist/index.css' //导入element样式
import 'element-plus/theme-chalk/dark/css-vars.css' //导入element黑暗样式
import './style.css' //导入自定义样式

创建style.css(可选,如果要自定义默认主题的话)

css
/* 设置tailwind更高优先级 */
@import "tailwindcss" important;

/* 设置默认主题的颜色,暗黑主题保持相同颜色,也可以单独写html.dark*/
html.dark,:root {
  /* 核心 primary 颜色 */
  --el-color-primary: #01c465;
  --el-color-primary-light-3: #8dffc4;   /* 悬停状态 */
  --el-color-primary-light-5: #cdfee0;   /* 浅色状态 */
  --el-color-primary-light-9: rgba(255, 255, 255, 0);   /* 浅色状态透明背景 */
  --el-color-primary-dark-1: #03c266;    /* 按下状态 */
  --el-color-primary-dark-2: #00a759;    /* 深度按下 */
  /* 边角圆度设置 - 统一设置更高的圆角 */
  --el-border-radius-base: 8px;         /* 基础圆角 (默认4px) */
  --el-border-radius-small: 4px;         /* 小圆角 (默认2px) */
}

vue组件中设置切换主题按钮

vue
<template>
  <el-button
    @click="toggleTheme"
    :icon="theme === 'light' ? Moon : Sunny"
    circle
    :title="getThemeLabel(theme)"
  />
</template>

<script setup lang="ts">
// 使用主题组合函数
import { useTheme } from '../utils/useTheme'
import { Moon, Sunny } from '@element-plus/icons-vue'

const { theme, toggleTheme, getThemeLabel } = useTheme()
</script>

出现两个.el-button + .el-button无法对齐解决办法

为父组件添加一个随意类名sidebar-tw

然后覆盖样式
<style scoped>
:deep(.sidebar-tw .el-button + .el-button) {
  margin-left: 0 !important;          /* 清除相邻左外边距,保留 Tailwind 的 gap      */  /* 中文注释 */
}
</style>

全局防抖

按钮防抖

ts
import type { Directive } from 'vue' //防抖引用
// 按钮防重复点击,调用方法<el-button v-load="2000" />
const loadingDirective: Directive = {
    mounted(el, binding) {
      el.addEventListener('click', () => {
        // 添加禁用状态
        el.disabled = true
        el.classList.add('is-disabled')
        
        // 指定时间后恢复
        setTimeout(() => {

        el.disabled = false
        el.classList.remove('is-disabled')
        }, binding.value || 2000)
      })
    }
  }

然后在main.ts中:
app.directive('load', loadingDirective) // 全局防重复点击