Vue3 + Element Plus 完整使用指南

Vue3 + Element Plus 完整使用指南

一、Element Plus 是什么?

Element Plus 是饿了么团队为 Vue 3 打造的一套桌面端 UI 组件库。它是 Element UI 的 Vue 3 版本,提供了丰富的组件,比如按钮、表单、表格、分页、弹窗等,能让你快速搭建出美观的管理后台。

官方文档:https://element-plus.org/zh-CN/


二、安装

2.1 创建 Vue 3 项目(如已有项目可跳过)

bash 复制代码
npm create vite@latest my-project -- --template vue
cd my-project
npm install

2.2 安装 Element Plus

bash 复制代码
npm install element-plus

三、引入方式(两种)

方式一:全量引入(推荐新手使用)

main.js 中一次性引入所有组件:

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')

优点 :配置简单,开箱即用,直接用 <el-button><el-table> 等标签即可。

缺点:打包体积较大,因为所有组件都会被打包进去。

方式二:按需引入(适合生产项目)

只引入你实际使用的组件,减小打包体积:

js 复制代码
import { createApp } from 'vue'
import { ElButton, ElTable, ElInput } from 'element-plus'
import 'element-plus/dist/index.css'
import App from './App.vue'

const app = createApp(App)

app.use(ElButton)
app.use(ElTable)
app.use(ElInput)

app.mount('#app')

💡 更推荐搭配 unplugin-vue-componentsunplugin-auto-import 实现自动按需引入,无需手动 import。


四、常用组件实战

下面以一个「人员信息管理系统」为例,演示常用组件的用法。

4.1 按钮(el-button)

html 复制代码
<el-button type="primary">新增</el-button>
<el-button type="danger">删除</el-button>
<el-button type="success">保存</el-button>
<el-button type="primary" link>编辑</el-button>   <!-- link 类型:文字按钮 -->

常用 type 值:

type 用途
primary 主要操作(蓝)
success 成功(绿)
warning 警告(橙)
danger 危险(红)
info 信息(灰)

4.2 表格(el-table)

表格是后台系统最常用的组件,用于展示列表数据:

html 复制代码
<el-table :data="list" border stripe>
  <el-table-column label="ID" prop="id" width="80"></el-table-column>
  <el-table-column label="姓名" prop="name" width="150"></el-table-column>
  <el-table-column label="籍贯" prop="place"></el-table-column>
  <el-table-column label="操作" width="150">
    <template #default="{ row }">
      <el-button type="primary" link @click="handleEdit(row)">编辑</el-button>
      <el-button type="danger" link @click="handleDelete(row.id)">删除</el-button>
    </template>
  </el-table-column>
</el-table>

关键属性说明:

属性 作用
:data 绑定数据源(数组)
border 显示边框
stripe 斑马纹效果
prop 对应数据中的字段名
#default 作用域插槽,{ row } 可以获取当前行数据

4.3 表单(el-form)

表单用于数据输入,配合弹窗使用非常常见:

html 复制代码
<el-form label-width="50px">
  <el-form-item label="姓名">
    <el-input v-model="formData.name" placeholder="请输入姓名" />
  </el-form-item>
  <el-form-item label="籍贯">
    <el-input v-model="formData.place" placeholder="请输入籍贯" />
  </el-form-item>
</el-form>

4.4 弹窗(el-dialog)

弹窗常用于新增/编辑操作:

html 复制代码
<el-dialog v-model="dialogVisible" title="编辑" width="400px">
  <!-- 弹窗内容 -->
  <el-form>...</el-form>

  <!-- 底部按钮插槽 -->
  <template #footer>
    <el-button @click="dialogVisible = false">取消</el-button>
    <el-button type="primary" @click="handleSave">确认</el-button>
  </template>
</el-dialog>

核心要点

  • v-model 控制弹窗的显示/隐藏
  • #footer 插槽用于自定义底部按钮

4.5 分页(el-pagination)

当数据量大时,需要分页展示:

html 复制代码
<el-pagination
  background
  layout="prev, pager, next"
  :total="list.length"
  :current-page="currentPage"
  :page-size="pageSize"
  @current-change="handlePageChange"
/>

关键属性:

属性 作用
:total 数据总条数
:current-page 当前页码(从 1 开始)
:page-size 每页显示条数
@current-change 页码改变时触发的事件
background 按钮显示背景色
layout 布局组件,逗号分隔

常用 layout 值:

复制代码
prev        上一页按钮
pager       页码列表
next        下一页按钮
total       显示总条数
sizes       每页条数选择器
 jumper     跳转到指定页

五、完整项目示例

下面是一个包含 列表展示、删除、编辑、分页 的完整示例:

5.1 项目结构

复制代码
src/
├── App.vue              ← 主页面
├── main.js              ← 入口文件
└── components/
    └── Edit.vue         ← 编辑弹窗组件

5.2 main.js --- 入口文件

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')

5.3 App.vue --- 主页面

html 复制代码
<script setup>
import { ref, computed } from 'vue'
import Edit from './components/Edit.vue'

// 列表数据
const list = ref([
  { id: 1, name: '张三', place: '北京' },
  { id: 2, name: '李四', place: '上海' },
  { id: 3, name: '王五', place: '广州' },
  { id: 4, name: '赵六', place: '深圳' },
  { id: 5, name: '孙七', place: '杭州' },
  { id: 6, name: '周八', place: '成都' },
  { id: 7, name: '吴九', place: '武汉' },
  { id: 8, name: '郑十', place: '南京' },
  { id: 9, name: '陈十一', place: '西安' },
  { id: 10, name: '林十二', place: '重庆' }
])

// ========== 分页相关 ==========
const currentPage = ref(1)
const pageSize = ref(5)

// 计算当前页显示的数据
const pageData = computed(() => {
  const start = (currentPage.value - 1) * pageSize.value
  const end = start + pageSize.value
  return list.value.slice(start, end)
})

const handlePageChange = (page) => {
  currentPage.value = page
}

// ========== 删除功能 ==========
const handleDelete = (id) => {
  const index = list.value.findIndex(item => item.id === id)
  if (index !== -1) {
    list.value.splice(index, 1)
  }
}

// ========== 编辑功能 ==========
const editRef = ref(null)

const handleEdit = (row) => {
  editRef.value.open({ ...row })
}

const handleSave = (formData) => {
  const index = list.value.findIndex(item => item.id === formData.id)
  if (index !== -1) {
    list.value[index] = { ...formData }
  }
}
</script>

<template>
  <div class="app">
    <el-table :data="pageData" border stripe>
      <el-table-column label="ID" prop="id" width="80"></el-table-column>
      <el-table-column label="姓名" prop="name" width="150"></el-table-column>
      <el-table-column label="籍贯" prop="place"></el-table-column>
      <el-table-column label="操作" width="150">
        <template #default="{ row }">
          <el-button type="primary" link @click="handleEdit(row)">编辑</el-button>
          <el-button type="danger" link @click="handleDelete(row.id)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <el-pagination
      background
      layout="prev, pager, next"
      :total="list.length"
      :current-page="currentPage"
      :page-size="pageSize"
      @current-change="handlePageChange"
    />
  </div>

  <Edit ref="editRef" @save="handleSave" />
</template>

<style scoped>
.app {
  width: 980px;
  margin: 100px auto 0;
}
</style>

5.4 Edit.vue --- 编辑弹窗子组件

html 复制代码
<script setup>
import { ref, defineExpose, defineEmits } from 'vue'

const emit = defineEmits(['save'])

// 弹窗开关
const dialogVisible = ref(false)

// 表单数据
const formData = ref({ id: '', name: '', place: '' })

// 打开弹窗(供父组件调用)
const open = (row) => {
  formData.value = { ...row }
  dialogVisible.value = true
}

// 保存
const handleSave = () => {
  emit('save', formData.value)
  dialogVisible.value = false
}

// 暴露 open 方法给父组件
defineExpose({ open })
</script>

<template>
  <el-dialog v-model="dialogVisible" title="编辑" width="400px">
    <el-form label-width="50px">
      <el-form-item label="姓名">
        <el-input v-model="formData.name" placeholder="请输入姓名" />
      </el-form-item>
      <el-form-item label="籍贯">
        <el-input v-model="formData.place" placeholder="请输入籍贯" />
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="dialogVisible = false">取消</el-button>
      <el-button type="primary" @click="handleSave">确认</el-button>
    </template>
  </el-dialog>
</template>

<style scoped>
.el-input {
  width: 290px;
}
</style>

六、父子组件通信要点

这个项目中涉及几个关键的父子组件通信方式,值得理解:

父调子:defineExpose + ref

js 复制代码
// 子组件:暴露方法
defineExpose({ open })

// 父组件:通过 ref 调用
const editRef = ref(null)
editRef.value.open(data)   // 调用子组件的 open 方法

子传父:defineEmits + emit

js 复制代码
// 子组件:声明并发射事件
const emit = defineEmits(['save'])
emit('save', formData)

// 父组件:监听事件
<Edit @save="handleSave" />

七、分页逻辑详解

分页的核心就是用 computed 计算当前页的数据:

复制代码
当前页数据 = list.slice((页码 - 1) * 每页条数, 页码 * 每页条数)

pageSize = 5 为例:

页码 截取范围 显示数据
1 0 ~ 5 第1 ~ 第5条
2 5 ~ 10 第6 ~ 第10条
3 10 ~ 15 第11 ~ 第15条

八、常见问题

Q1:引入后样式没有生效?

忘记引入 import 'element-plus/dist/index.css',这是最常见的问题。

Q2:组件没有显示?

确认 main.js 中有 app.use(ElementPlus),否则组件不会被注册。

Q3:表格数据不更新?

确保绑定的数据是响应式的(使用 refreactive),不要直接操作非响应式数据。

Q4:弹窗打不开?

检查 v-model="dialogVisible" 中的变量是否是 ref,且模板中访问的是 dialogVisible 而不是 dialogVisible.value(模板中会自动解包)。


总结

步骤 操作
1️⃣ npm install element-plus
2️⃣ main.jsimport ElementPlus + app.use(ElementPlus)
3️⃣ 组件中直接使用 <el-xxx> 标签
4️⃣ 数据用 ref 管理,保证响应式

Element Plus 的官方文档 https://element-plus.org/zh-CN/ 有每个组件的完整 API,遇到不确定的属性可以随时查阅。

相关推荐
To_OC12 小时前
LC 207 课程表:刚学图论那会儿,我连这是拓扑排序都没看出来
javascript·算法·leetcode
To_OC12 小时前
LC 208 实现 Trie 前缀树:曾被名字劝退,写完发现是送分题
javascript·算法·leetcode
天渺工作室12 小时前
实现一个adblock/adblock plus等浏览器广告拦截器检测插件
前端·javascript
阳光是sunny13 小时前
Vue 项目怎么做用户行为全链路监控?轻量插件方案详解
前端·面试·架构
ZhengEnCi13 小时前
Q04-Vite禁用CSS代码分割-解决生产环境样式加载顺序混乱问题
前端·vue.js·vite
九酒13 小时前
AI Agent 开发踩坑记:口播功能非得用 APP 原生实现吗?
前端·人工智能·agent
Jackson__14 小时前
做了一段时间的AI coding后,我终于搞清了 CLI 和 MCP 的区别
前端·agent·ai编程
IT_陈寒17 小时前
JavaScript项目实战经验分享
前端·人工智能·后端
用户479492835691517 小时前
6w star,GitHub 趋势第一的 Ponytail,这个agent插件到底在火什么
前端·后端
薛定喵的谔19 小时前
我开源了一个精致的 Next.js 博客模板:Skyplume
前端·前端框架·next.js