在 Vue 项目开发中,UI 组件库是提升开发效率、保证界面一致性的核心工具。Element UI(适配 Vue 2)和 Element Plus(适配 Vue 3)作为国内最主流的 Vue 组件库之一,凭借丰富的组件、完善的文档和良好的扩展性,成为中后台系统、企业级应用的首选。本文将从实战角度出发,分享 Element UI/Plus 组件的灵活使用技巧,帮助开发者避开常见坑点,最大化发挥组件库的价值。
一、基础准备:快速接入 Element UI/Plus
1. 环境适配与安装
首先明确项目的 Vue 版本,选择对应的组件库:
- Vue 2 + Element UI:
# npm安装 npm i element-ui -S # 全局引入(main.js) import Vue from 'vue' import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' Vue.use(ElementUI)- Vue 3 + Element Plus:
# npm安装 npm install element-plus --save # 全局引入(main.js) import { createApp } from 'vue' import ElementPlus from '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-components插件:
# 安装插件 npm install unplugin-vue-components unplugin-auto-import -D配置vite.config.js(Vite 项目):
import { defineConfig } from 'vite' 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: [ AutoImport({ resolvers: [ElementPlusResolver()], }), Components({ resolvers: [ElementPlusResolver()], }), ], })配置后,使用组件时无需手动 import,插件会自动按需引入组件和样式。
二、核心组件实战:灵活使用技巧
1. Table 组件:复杂数据展示与交互
Table 是中后台系统的核心组件,掌握这些技巧可应对 80% 的场景:
(1)自定义列渲染
通过scoped-slot(Vue 2)或v-slot(Vue 3)实现自定义内容,比如状态标签、操作按钮:
<!-- Element Plus示例 --> <el-table :data="tableData" border> <el-table-column prop="name" label="姓名" /> <el-table-column prop="status" label="状态"> <template v-slot="scope"> <el-tag :type="scope.row.status === 'active' ? 'success' : 'danger'"> {{ scope.row.status === 'active' ? '已激活' : '已禁用' }} </el-tag> </template> </el-table-column> <el-table-column label="操作" width="200"> <template v-slot="scope"> <el-button size="small" type="primary" @click="editRow(scope.row)">编辑</el-button> <el-button size="small" type="danger" @click="deleteRow(scope.row)">删除</el-button> </template> </el-table-column> </el-table>(2)动态列与列筛选
根据业务需求动态控制列的显示 / 隐藏,提升表格灵活性:
<template> <div> <!-- 列筛选按钮 --> <el-checkbox-group v-model="showColumns" @change="handleColumnChange"> <el-checkbox label="name">姓名</el-checkbox> <el-checkbox label="age">年龄</el-checkbox> <el-checkbox label="status">状态</el-checkbox> </el-checkbox-group> <el-table :data="tableData" border> <el-table-column v-if="showColumns.includes('name')" prop="name" label="姓名" /> <el-table-column v-if="showColumns.includes('age')" prop="age" label="年龄" /> <el-table-column v-if="showColumns.includes('status')" prop="status" label="状态"> <!-- 自定义渲染 --> </el-table-column> </el-table> </div> </template> <script setup> import { ref } from 'vue' const showColumns = ref(['name', 'age', 'status']) const tableData = ref([ { name: '张三', age: 25, status: 'active' }, { name: '李四', age: 30, status: 'disabled' } ]) const handleColumnChange = () => { // 列切换逻辑 } </script>(3)表格懒加载与树形结构
Element Plus 的 Table 支持树形数据和懒加载,适合展示层级数据:
<el-table :data="treeData" border lazy :load="loadMore" row-key="id" :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" > <el-table-column prop="name" label="名称" /> <el-table-column prop="desc" label="描述" /> </el-table>2. Form 组件:高效表单开发
表单是前端开发的高频场景,Element UI/Plus 的 Form 组件提供了丰富的校验、布局能力:
(1)表单校验优化
内置校验规则满足基础需求,自定义校验可处理复杂场景:
<el-form :model="form" :rules="rules" ref="formRef" label-width="100px"> <el-form-item label="手机号" prop="phone"> <el-input v-model="form.phone" placeholder="请输入手机号" /> </el-form-item> <el-form-item label="密码" prop="password"> <el-input v-model="form.password" type="password" placeholder="请输入密码" /> </el-form-item> <el-form-item> <el-button type="primary" @click="submitForm">提交</el-button> </el-form-item> </el-form>// Vue 3 + Setup import { ref } from 'vue' const formRef = ref(null) const form = ref({ phone: '', password: '' }) // 校验规则 const rules = ref({ phone: [ { required: true, message: '请输入手机号', trigger: 'blur' }, { pattern: /^1[3-9]\d{9}$/, message: '手机号格式错误', trigger: 'blur' } ], password: [ { required: true, message: '请输入密码', trigger: 'blur' }, { min: 6, max: 16, message: '密码长度6-16位', trigger: 'blur' }, // 自定义校验 { validator: validatePassword, trigger: 'blur' } ] }) // 自定义密码校验(包含字母+数字) const validatePassword = (rule, value, callback) => { if (!/^(?=.*[a-zA-Z])(?=.*\d).+$/.test(value)) { callback(new Error('密码必须包含字母和数字')) } else { callback() } } // 提交表单 const submitForm = () => { formRef.value.validate((valid) => { if (valid) { // 校验通过,提交接口 console.log('表单提交:', form.value) } else { console.log('表单校验失败') return false } }) }(2)动态表单项
支持根据用户操作动态添加 / 删除表单项,比如多联系人、多地址场景:
<el-form :model="dynamicForm" ref="dynamicFormRef" label-width="100px"> <div v-for="(item, index) in dynamicForm.contacts" :key="index"> <el-form-item label="联系人" :prop="`contacts[${index}].name`" :rules="[{ required: true, message: '请输入姓名' }]"> <el-input v-model="item.name" /> </el-form-item> <el-form-item label="电话" :prop="`contacts[${index}].phone`" :rules="[{ required: true, message: '请输入电话' }]"> <el-input v-model="item.phone" /> </el-form-item> <el-button type="danger" size="small" @click="removeContact(index)">删除</el-button> </div> <el-button type="primary" size="small" @click="addContact">添加联系人</el-button> </el-form>const dynamicForm = ref({ contacts: [{ name: '', phone: '' }] }) // 添加联系人 const addContact = () => { dynamicForm.value.contacts.push({ name: '', phone: '' }) } // 删除联系人 const removeContact = (index) => { dynamicForm.value.contacts.splice(index, 1) }3. Dialog 组件:优雅的弹窗交互
Dialog 组件易踩坑点在于重复渲染、数据隔离,推荐以下使用方式:
(1)封装可复用弹窗组件
将弹窗抽离为独立组件,通过v-model控制显隐,实现数据解耦:
<!-- MyDialog.vue --> <template> <el-dialog v-model="visible" title="编辑信息" width="500px" @close="handleClose" > <el-form :model="form" label-width="80px"> <el-form-item label="姓名"> <el-input v-model="form.name" /> </el-form-item> </el-form> <template v-slot:footer> <el-button @click="visible = false">取消</el-button> <el-button type="primary" @click="handleConfirm">确认</el-button> </template> </el-dialog> </template> <script setup> import { defineProps, defineEmits, ref, watch } from 'vue' const props = defineProps({ modelValue: { type: Boolean, default: false }, rowData: { type: Object, default: () => ({}) } }) const emit = defineEmits(['update:modelValue', 'confirm']) const visible = ref(false) const form = ref({}) // 监听显隐状态 watch(() => props.modelValue, (val) => { visible.value = val // 打开弹窗时初始化数据 if (val) { form.value = { ...props.rowData } } }) // 关闭弹窗 const handleClose = () => { emit('update:modelValue', false) } // 确认提交 const handleConfirm = () => { emit('confirm', form.value) handleClose() } </script>使用封装后的弹窗:
<template> <el-button @click="dialogVisible = true">打开弹窗</el-button> <my-dialog v-model="dialogVisible" :row-data="selectedRow" @confirm="handleDialogConfirm" /> </template> <script setup> import { ref } from 'vue' import MyDialog from './MyDialog.vue' const dialogVisible = ref(false) const selectedRow = ref({ name: '张三' }) const handleDialogConfirm = (formData) => { console.log('弹窗确认数据:', formData) } </script>三、进阶技巧:定制化与性能优化
1. 样式定制
Element UI/Plus 支持多种样式定制方式,满足品牌化需求:
- 全局主题修改:通过 SCSS 变量覆盖(推荐),新建
element-variables.scss:
// Element Plus 主题变量覆盖 @forward 'element-plus/theme-chalk/src/common/var.scss' with ( $colors: ( primary: ( base: #409eff, // 主色 ), success: ( base: #67c23a, ) ) );在main.js引入该文件,替换默认样式。
- 局部样式穿透:使用
::v-deep(Vue 2)或:deep()(Vue 3)修改组件局部样式:
:deep(.el-button) { background-color: #1890ff; border-color: #1890ff; }2. 性能优化
- 避免不必要的重渲染:对 Table、Form 等复杂组件,使用
v-memo缓存渲染结果(Vue 3):
<el-table :data="tableData" v-memo="[tableData.length, activeTab]"> <!-- 列定义 --> </el-table>- 懒加载组件:通过
defineAsyncComponent异步加载非首屏组件:
import { defineAsyncComponent } from 'vue' const MyDialog = defineAsyncComponent(() => import('./MyDialog.vue'))- 减少监听深度:对表单、表格数据监听时,指定具体字段,避免深度监听:
watch(() => form.value.phone, (newVal) => { // 仅监听手机号变化 })四、常见问题与解决方案
- Element Plus 图标不显示:Element Plus 2.0 + 需单独安装图标库:
npm install @element-plus/icons-vue全局注册图标:
import * as ElementPlusIconsVue from '@element-plus/icons-vue' const app = createApp(App) for (const [key, component] of Object.entries(ElementPlusIconsVue)) { app.component(key, component) }- Table 组件数据更新但视图不刷新:因 Vue 响应式限制,直接修改数组元素 / 对象属性可能不触发更新,需使用
$set(Vue 2)或解构赋值(Vue 3):
// Vue 3示例 tableData.value[index] = { ...tableData.value[index], status: 'active' }- Form 校验不生效:确保
prop属性与表单模型字段一致,且rules规则格式正确;动态表单项需使用数组下标指定prop(如contacts[0].name)。
五、总结
Element UI/Plus 作为成熟的 Vue 组件库,其价值不仅在于提供开箱即用的组件,更在于通过灵活的配置、自定义能力适配复杂业务场景。本文从基础接入、核心组件实战、进阶定制到性能优化,覆盖了开发中的核心场景与技巧。
实际开发中,建议优先使用按需引入减少包体积,结合业务封装可复用组件(如表格、表单、弹窗),同时关注组件的性能与用户体验。掌握这些技巧后,能够高效开发出美观、稳定的 Vue 应用,充分发挥 Element UI/Plus 的优势。
最后,建议持续关注 Element Plus 的官方文档和更新日志,及时适配新特性,同时结合 Vue 的最新特性(如 Composition API、Teleport 等),进一步提升开发效率和项目质量。