Element Plus 从入门到实战:Vue3 组件库快速上手,高效开发后台管理系统

0 阅读12分钟

前言

作为 Vue3 生态中最热门的 UI 组件库之一,Element Plus 凭借 “丰富的组件、完善的文档、良好的兼容性”,成为前端开发者开发后台管理系统、中后台应用的首选。无论是新手快速搭建项目原型,还是资深开发者提升开发效率,Element Plus 都能大幅降低 UI 开发成本,让你专注于业务逻辑而非样式编写。

本文从 “入门配置→核心组件实战→项目优化” 三个维度,结合后台管理系统的真实场景,手把手教你掌握 Element Plus 的使用技巧。无论你是 Vue3 新手,还是想从 Element UI 迁移到 Element Plus,这篇文章都能让你快速上手、少走弯路!

一、Element Plus 入门:环境搭建与基础配置

在使用 Element Plus 前,需先完成 Vue3 项目的创建和组件库的安装配置。以下是完整步骤,兼容 Vite 和 Vue CLI 两种构建工具。

1. 前提条件

  • 已安装 Node.js(推荐 v14.18 + 或 v16+);
  • 已创建 Vue3 项目(Vite 或 Vue CLI 均可);
  • 熟悉 Vue3 基础语法(Composition API 优先)。

2. 安装 Element Plus

根据项目构建工具选择对应的安装命令,推荐使用npmpnpm

(1)npm 安装

bash

npm install element-plus --save

(2)pnpm 安装(推荐,速度更快)

bash

pnpm add element-plus

(3)Vue CLI 项目额外依赖

若项目基于 Vue CLI 创建,需安装配套插件:

bash

npm install unplugin-vue-components unplugin-auto-import -D

3. 配置 Element Plus(两种方式)

Element Plus 支持 “全局引入” 和 “按需引入”,推荐按需引入以减小项目体积。

(1)全局引入(快速原型开发)

main.js中全局注册所有组件,简单粗暴但会增加打包体积:

javascript

运行

import { createApp } from 'vue'
import ElementPlus from 'element-plus' // 引入Element Plus
import 'element-plus/dist/index.css' // 引入全局样式
import App from './App.vue'

const app = createApp(App)
app.use(ElementPlus) // 全局注册
app.mount('#app')

(2)按需引入(项目实战首选)

通过unplugin-vue-componentsunplugin-auto-import插件,实现组件和 API 的自动导入,无需手动注册:

步骤 1:配置 Vite(vite.config.js)

javascript

运行

import { defineConfig } from 'vite'
import Vue from '@vitejs/plugin-vue'
// 引入Element Plus按需导入插件
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

export default defineConfig({
  plugins: [
    Vue(),
    // 自动导入Element Plus的API(如ElMessage、ElMessageBox)
    AutoImport({
      resolvers: [ElementPlusResolver()]
    }),
    // 自动导入Element Plus的组件
    Components({
      resolvers: [ElementPlusResolver()]
    })
  ]
})

步骤 2:配置 Vue CLI(vue.config.js)

javascript

运行

const { defineConfig } = require('@vue/cli-service')
const AutoImport = require('unplugin-auto-import/webpack')
const Components = require('unplugin-vue-components/webpack')
const { ElementPlusResolver } = require('unplugin-vue-components/resolvers')

module.exports = defineConfig({
  configureWebpack: {
    plugins: [
      AutoImport({
        resolvers: [ElementPlusResolver()]
      }),
      Components({
        resolvers: [ElementPlusResolver()]
      })
    ]
  }
})

效果:使用组件无需手动导入

vue

<!-- 无需在组件内import ElButton,直接使用 -->
<template>
  <el-button type="primary">按钮</el-button>
</template>

4. 国际化配置(可选)

Element Plus 默认支持中文,若需切换为英文等其他语言,可在main.js中配置:

javascript

运行

import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
// 引入英文语言包
import en from 'element-plus/dist/locale/en.mjs'
import App from './App.vue'

const app = createApp(App)
app.use(ElementPlus, { locale: en })
app.mount('#app')

二、核心组件实战:后台管理系统高频场景

Element Plus 提供了 100 + 组件,覆盖表单、表格、弹窗、导航等中后台开发的核心场景。以下聚焦 5 个高频组件,结合真实业务需求讲解使用技巧。

1. 布局组件:ElContainer + ElRow/ElCol(页面骨架搭建)

后台管理系统的页面通常分为 “顶部导航栏 + 侧边栏 + 主内容区”,使用 Element Plus 的布局组件可快速实现响应式布局。

实战:后台管理系统基础布局

vue

<template>
  <!-- 外层容器:垂直布局 -->
  <el-container style="height: 100vh;">
    <!-- 顶部导航栏 -->
    <el-header style="background-color: #fff; border-bottom: 1px solid #e5e7eb;">
      <div class="header-left">Element Plus 后台管理系统</div>
      <div class="header-right">
        <el-dropdown>
          <span class="user-name">张三</span>
          <template #dropdown>
            <el-dropdown-menu>
              <el-dropdown-item>个人中心</el-dropdown-item>
              <el-dropdown-item>退出登录</el-dropdown-item>
            </el-dropdown-menu>
          </template>
        </el-dropdown>
      </div>
    </el-header>

    <!-- 中间容器:水平布局(侧边栏+主内容区) -->
    <el-container>
      <!-- 侧边栏 -->
      <el-aside width="200px" style="background-color: #fff; border-right: 1px solid #e5e7eb;">
        <el-menu :default-active="activeMenu" class="el-menu-vertical-demo">
          <el-menu-item index="/dashboard">
            <el-icon><Home /></el-icon>
            <span>仪表盘</span>
          </el-menu-item>
          <el-sub-menu index="/user">
            <template #title>
              <el-icon><User /></el-icon>
              <span>用户管理</span>
            </template>
            <el-menu-item index="/user/list">用户列表</el-menu-item>
            <el-menu-item index="/user/add">新增用户</el-menu-item>
          </el-sub-menu>
          <el-menu-item index="/order">
            <el-icon><ShoppingCart /></el-icon>
            <span>订单管理</span>
          </el-menu-item>
        </el-menu>
      </el-aside>

      <!-- 主内容区 -->
      <el-main style="padding: 20px; overflow-y: auto;">
        <!-- 路由占位符,对应不同页面内容 -->
        <router-view />
      </el-main>
    </el-container>
  </el-container>
</template>

<script setup>
import { ref } from 'vue'
// 引入图标(Element Plus需单独引入图标库)
import { Home, User, ShoppingCart } from '@element-plus/icons-vue'

const activeMenu = ref('/dashboard') // 当前激活的菜单
</script>

<style scoped>
.header-left {
  font-size: 18px;
  font-weight: 600;
  color: #1989fa;
}
.header-right {
  display: flex;
  align-items: center;
  gap: 16px;
}
.user-name {
  cursor: pointer;
}
.el-menu-vertical-demo {
  height: 100%;
  border-right: none;
}
</style>

关键技巧:

  • el-container支持direction属性(vertical/horizontal),控制子元素排列方向;
  • el-asidewidth可设置固定值或百分比,响应式场景可结合媒体查询动态调整;
  • 菜单激活状态通过default-active绑定,配合路由守卫可实现菜单与路由同步。

2. 表格组件:ElTable(数据展示与操作)

表格是后台管理系统的核心组件,用于展示用户列表、订单数据等。Element Plus 的ElTable支持排序、筛选、分页、单元格编辑等功能,满足大部分业务需求。

实战:用户列表表格(带分页、搜索、删除功能)

vue

<template>
  <div class="user-list">
    <!-- 搜索栏 -->
    <div class="search-bar" style="margin-bottom: 20px;">
      <el-input v-model="searchKey" placeholder="输入用户名搜索" style="width: 300px; margin-right: 10px;" />
      <el-button type="primary" @click="fetchUserList">搜索</el-button>
      <el-button type="success" @click="goToAddUser">新增用户</el-button>
    </div>

    <!-- 表格 -->
    <el-table :data="userList" border stripe style="width: 100%;">
      <el-table-column label="ID" prop="id" width="80" align="center" />
      <el-table-column label="用户名" prop="username" align="center" />
      <el-table-column label="手机号" prop="phone" align="center" />
      <el-table-column label="角色" prop="role" align="center">
        <template #default="scope">
          <el-tag :type="scope.row.role === 'admin' ? 'primary' : 'success'">
            {{ scope.row.role === 'admin' ? '管理员' : '普通用户' }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column label="状态" prop="status" align="center">
        <template #default="scope">
          <el-switch 
            v-model="scope.row.status" 
            active-value="active" 
            inactive-value="inactive"
            @change="updateUserStatus(scope.row)"
          />
        </template>
      </el-table-column>
      <el-table-column label="操作" align="center" width="180">
        <template #default="scope">
          <el-button type="text" @click="goToEditUser(scope.row)">编辑</el-button>
          <el-button type="text" text-color="#ff4d4f" @click="deleteUser(scope.row.id)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <!-- 分页 -->
    <div class="pagination" style="margin-top: 20px; text-align: right;">
      <el-pagination
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="currentPage"
        :page-sizes="[10, 20, 50, 100]"
        :page-size="pageSize"
        :total="total"
        layout="total, sizes, prev, pager, next, jumper"
      />
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'

const router = useRouter()

// 搜索条件
const searchKey = ref('')
// 表格数据
const userList = ref([])
// 分页参数
const currentPage = ref(1)
const pageSize = ref(10)
const total = ref(0)

// 初始化加载用户列表
fetchUserList()

// 模拟请求用户列表数据
function fetchUserList() {
  // 实际开发中替换为接口请求
  setTimeout(() => {
    const mockData = Array.from({ length: pageSize.value }, (_, i) => ({
      id: (currentPage.value - 1) * pageSize.value + i + 1,
      username: `用户${(currentPage.value - 1) * pageSize.value + i + 1}`,
      phone: `1380013800${i}`,
      role: i % 3 === 0 ? 'admin' : 'user',
      status: 'active'
    }))
    userList.value = mockData
    total.value = 100 // 模拟总数据量
  }, 500)
}

// 每页条数改变
function handleSizeChange(val) {
  pageSize.value = val
  currentPage.value = 1 // 重置为第一页
  fetchUserList()
}

// 页码改变
function handleCurrentChange(val) {
  currentPage.value = val
  fetchUserList()
}

// 新增用户
function goToAddUser() {
  router.push('/user/add')
}

// 编辑用户
function goToEditUser(user) {
  router.push({ path: '/user/edit', query: { id: user.id } })
}

// 更新用户状态
function updateUserStatus(user) {
  ElMessage.success(`用户${user.username}状态已更新为${user.status === 'active' ? '启用' : '禁用'}`)
  // 实际开发中调用接口更新状态
}

// 删除用户
function deleteUser(userId) {
  ElMessage.success(`用户ID${userId}已删除`)
  // 实际开发中调用接口删除数据,删除后重新加载列表
  fetchUserList()
}
</script>

关键技巧:

  • 表格数据通过data属性绑定,prop对应数据字段,label为列标题;
  • 自定义单元格内容使用#default="scope"插槽,scope.row获取当前行数据;
  • 分页组件通过size-changecurrent-change事件监听页码、每页条数变化,同步请求数据;
  • stripe属性开启斑马纹,border属性显示边框,提升表格可读性。

3. 表单组件:ElForm(数据提交与校验)

表单用于新增 / 编辑用户、配置参数等场景,Element Plus 的ElForm支持丰富的校验规则、表单布局和组件联动,无需手动编写复杂校验逻辑。

实战:新增用户表单(带表单校验)

vue

<template>
  <el-card title="新增用户">
    <el-form :model="userForm" :rules="formRules" ref="userFormRef" label-width="100px">
      <el-form-item label="用户名" prop="username">
        <el-input v-model="userForm.username" placeholder="请输入用户名" />
      </el-form-item>
      <el-form-item label="手机号" prop="phone">
        <el-input v-model="userForm.phone" placeholder="请输入手机号" />
      </el-form-item>
      <el-form-item label="密码" prop="password">
        <el-input v-model="userForm.password" type="password" placeholder="请输入密码" />
      </el-form-item>
      <el-form-item label="确认密码" prop="confirmPassword">
        <el-input v-model="userForm.confirmPassword" type="password" placeholder="请确认密码" />
      </el-form-item>
      <el-form-item label="角色" prop="role">
        <el-select v-model="userForm.role" placeholder="请选择角色">
          <el-option label="管理员" value="admin" />
          <el-option label="普通用户" value="user" />
        </el-select>
      </el-form-item>
      <el-form-item label="状态" prop="status">
        <el-select v-model="userForm.status" placeholder="请选择状态">
          <el-option label="启用" value="active" />
          <el-option label="禁用" value="inactive" />
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="submitForm">提交</el-button>
        <el-button @click="resetForm">重置</el-button>
      </el-form-item>
    </el-form>
  </el-card>
</template>

<script setup>
import { ref } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'

const router = useRouter()
const userFormRef = ref(null) // 表单引用

// 表单数据
const userForm = ref({
  username: '',
  phone: '',
  password: '',
  confirmPassword: '',
  role: 'user',
  status: 'active'
})

// 表单校验规则
const formRules = ref({
  username: [
    { required: true, message: '请输入用户名', trigger: 'blur' },
    { min: 3, max: 10, message: '用户名长度为3-10个字符', trigger: 'blur' }
  ],
  phone: [
    { required: true, message: '请输入手机号', trigger: 'blur' },
    { pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号格式', trigger: 'blur' }
  ],
  password: [
    { required: true, message: '请输入密码', trigger: 'blur' },
    { min: 6, max: 20, message: '密码长度为6-20个字符', trigger: 'blur' }
  ],
  confirmPassword: [
    { required: true, message: '请确认密码', trigger: 'blur' },
    { 
      validator: (rule, value, callback) => {
        if (value !== userForm.value.password) {
          callback(new Error('两次输入密码不一致'))
        } else {
          callback()
        }
      },
      trigger: 'blur'
    }
  ],
  role: [
    { required: true, message: '请选择角色', trigger: 'change' }
  ]
})

// 提交表单
function submitForm() {
  userFormRef.value.validate((isValid) => {
    if (isValid) {
      // 表单校验通过,调用接口提交数据
      setTimeout(() => {
        ElMessage.success('用户新增成功!')
        router.push('/user/list') // 跳转回用户列表
      }, 500)
    } else {
      ElMessage.error('表单校验失败,请检查输入内容')
      return false
    }
  })
}

// 重置表单
function resetForm() {
  userFormRef.value.resetFields() // 重置表单字段和校验状态
}
</script>

关键技巧:

  • 表单数据通过model绑定,校验规则通过rules定义,prop需与表单字段名一致;
  • 自定义校验规则使用validator函数,适合处理 “两次密码一致” 等联动校验;
  • 提交表单前调用validate方法进行校验,isValidtrue表示校验通过;
  • 重置表单使用resetFields方法,可清空字段值并重置校验状态。

4. 弹窗组件:ElDialog(模态框交互)

弹窗用于展示详情、确认操作、表单填写等场景,Element Plus 的ElDialog支持拖拽、全屏、遮罩层控制等功能,使用灵活。

实战:查看用户详情弹窗

vue

<template>
  <!-- 触发弹窗的按钮 -->
  <el-button type="text" @click="openDetailDialog(user)">查看详情</el-button>

  <!-- 详情弹窗 -->
  <el-dialog
    v-model="isDialogOpen"
    title="用户详情"
    width="500px"
    :append-to-body="true"
    :close-on-click-modal="false"
  >
    <el-form :model="currentUser" label-width="100px" disabled>
      <el-form-item label="ID">
        <el-input v-model="currentUser.id" disabled />
      </el-form-item>
      <el-form-item label="用户名">
        <el-input v-model="currentUser.username" disabled />
      </el-form-item>
      <el-form-item label="手机号">
        <el-input v-model="currentUser.phone" disabled />
      </el-form-item>
      <el-form-item label="角色">
        <el-input v-model="currentUser.role === 'admin' ? '管理员' : '普通用户'" disabled />
      </el-form-item>
      <el-form-item label="状态">
        <el-input v-model="currentUser.status === 'active' ? '启用' : '禁用'" disabled />
      </el-form-item>
      <el-form-item label="创建时间">
        <el-input v-model="currentUser.createTime" disabled />
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="isDialogOpen = false">关闭</el-button>
    </template>
  </el-dialog>
</template>

<script setup>
import { ref } from 'vue'

// 弹窗显示状态
const isDialogOpen = ref(false)
// 当前查看的用户信息
const currentUser = ref({})

// 打开弹窗
function openDetailDialog(user) {
  // 模拟请求用户详情数据
  setTimeout(() => {
    currentUser.value = {
      ...user,
      createTime: '2024-01-01 10:00:00' // 模拟创建时间
    }
    isDialogOpen.value = true
  }, 300)
}
</script>

关键技巧:

  • 弹窗显示 / 隐藏通过v-model绑定布尔值控制;
  • append-to-body="true"将弹窗挂载到body元素下,避免被父元素样式影响;
  • close-on-click-modal="false"禁止点击遮罩层关闭弹窗,适合表单填写等场景;
  • 弹窗底部按钮通过#footer插槽自定义,默认显示 “确定” 和 “取消” 按钮。

5. 消息提示:ElMessage/ElMessageBox(交互反馈)

消息提示用于向用户反馈操作结果(成功、失败、警告),Element Plus 提供了ElMessage(轻量级提示)和ElMessageBox(确认对话框)两种组件。

实战:常见消息提示场景

javascript

运行

import { ElMessage, ElMessageBox } from 'element-plus'

// 成功提示
ElMessage.success('操作成功!')

// 错误提示
ElMessage.error('操作失败,请重试!')

// 警告提示
ElMessage.warning('请注意,数据已过期!')

// 信息提示
ElMessage.info('数据加载中...')

// 确认对话框(删除、提交等危险操作)
ElMessageBox.confirm(
  '此操作将永久删除该用户,是否继续?',
  '警告',
  {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }
).then(() => {
  // 点击确定后的逻辑
  ElMessage.success('删除成功!')
}).catch(() => {
  // 点击取消后的逻辑
  ElMessage.info('已取消删除')
})

三、项目优化:Element Plus 使用进阶技巧

1. 图标优化:按需引入图标库

Element Plus 的图标需要单独安装依赖,推荐按需引入以减小体积:

(1)安装图标库

bash

npm install @element-plus/icons-vue --save

(2)按需引入图标(推荐)

vue

<template>
  <el-button type="primary">
    <el-icon><Home /></el-icon>
    首页
  </el-button>
</template>

<script setup>
import { Home } from '@element-plus/icons-vue'
</script>

(3)全局引入所有图标(不推荐)

javascript

运行

import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import App from './App.vue'

const app = createApp(App)
app.use(ElementPlus)
// 全局注册所有图标
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
  app.component(key, component)
}
app.mount('#app')

2. 样式自定义:修改主题颜色

Element Plus 支持通过 CSS 变量或 SCSS 变量自定义主题颜色,满足项目品牌需求。

(1)CSS 变量方式(简单快捷)

main.js或全局样式文件中添加:

css

/* 自定义主题颜色(primary为主要颜色) */
:root {
  --el-color-primary: #165dff; /* 自定义主色 */
  --el-color-success: #00b42a; /* 自定义成功色 */
  --el-color-warning: #ff7d00; /* 自定义警告色 */
  --el-color-danger: #f53f3f; /* 自定义危险色 */
}

(2)SCSS 变量方式(灵活度更高)

需先安装 SCSS 依赖:

bash

npm install sass sass-loader --save-dev

创建element-variables.scss文件:

scss

// 覆盖Element Plus的SCSS变量
$--color-primary: #165dff;
$--color-success: #00b42a;
$--border-radius-base: 4px; // 自定义边框圆角

// 引入Element Plus的SCSS文件
@import "element-plus/packages/theme-chalk/src/index.scss";

vite.config.js中配置:

javascript

运行

import { defineConfig } from 'vite'
import Vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [Vue()],
  css: {
    preprocessorOptions: {
      scss: {
        additionalData: `@import "./src/assets/styles/element-variables.scss";`
      }
    }
  }
})

3. 性能优化:减少不必要的组件渲染

  • 避免在v-for中使用ElTable等复杂组件,如需循环渲染,可使用v-memo缓存;
  • 表单组件的rules尽量静态定义,避免动态生成导致频繁校验;
  • 弹窗组件使用v-if而非v-show,减少页面初始化时的 DOM 渲染压力。

4. 兼容性处理:适配低版本浏览器

Element Plus 默认不支持 IE11,若需兼容,需添加以下配置:

bash

# 安装polyfill依赖
npm install @babel/polyfill core-js@3 --save

main.js中引入:

javascript

运行

import 'core-js/stable'
import 'regenerator-runtime/runtime'

四、常见问题与解决方案

1. 组件样式不生效?

  • 检查是否引入element-plus/dist/index.css全局样式;
  • 按需引入时,确保unplugin-vue-componentsunplugin-auto-import配置正确;
  • 避免使用scoped样式覆盖组件样式,如需覆盖,可使用::v-deep:deep()

2. 图标不显示?

  • 检查是否安装@element-plus/icons-vue依赖;
  • 确认图标是否正确引入(按需引入需单独导入对应图标);
  • 全局引入图标时,确保循环注册组件的代码正确。

3. 表单校验不生效?

  • 检查prop属性是否与表单字段名一致;
  • 校验规则的trigger属性是否正确(blur为失焦触发,change为值变化触发);
  • 自定义校验规则中,callback必须调用(成功调用callback(),失败调用callback(new Error('提示信息')))。

4. 弹窗被父元素遮挡?

  • 设置append-to-body="true",将弹窗挂载到body下;
  • 调整弹窗的z-index属性,确保层级高于父元素。

总结

Element Plus 作为 Vue3 生态的核心 UI 组件库,其优势在于 “组件丰富、文档详细、上手简单”,尤其适合快速开发中后台系统。本文通过 “环境配置→核心组件实战→进阶优化” 的流程,覆盖了开发中的高频场景,只要掌握这些技巧,就能高效完成 UI 开发。

在实际项目中,建议结合 Element Plus 的官方文档(element-plus.org/zh-CN/)进行学习,文档中包含了所有组件的详细用法和示例。同时,根据项目需求灵活选择 “全局引入” 或 “按需引入”,兼顾开发效率和项目体积。

最后,祝大家使用 Element Plus 开发顺利!如果本文对你有帮助,欢迎点赞、收藏、转发~ 评论区可以分享你的使用经验或遇到的问题,一起交流学习!