day4 element plus+vue3+vite实现简单学习任务管理
Element Plus 是基于 Vue 3 的桌面端组件库,封装了大量开箱即用的 UI 组件,无需手写复杂样式,可快速搭建后台、管理类页面。在 main.ts/main.js 中全局注册 Element Plus,同时引入组件库样式,这是所有组件正常渲染的基础。表单系列组件(el-form / el-form-item / el-input / el-select)使用前提:项目中安装 elem
(一)Element Plus 基础介绍
Element Plus 是基于 Vue 3 的桌面端组件库,封装了大量开箱即用的 UI 组件,无需手写复杂样式,可快速搭建后台、管理类页面。
使用前提:项目中安装 element-plus 依赖,并在入口文件统一引入组件与全局样式。
(二)核心使用步骤
入口文件引入
在 main.ts/main.js 中全局注册 Element Plus,同时引入组件库样式,这是所有组件正常渲染的基础。
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')
组件基本使用规则
所有 Element Plus 组件标签均以 el- 开头,例如 <el-button>、<el-table>;支持内置属性、插槽、事件,用法和原生标签、Vue 语法完全兼容。
(三)常用组件用法详解
- 按钮组件 el-button
基础交互组件,支持不同类型、样式,绑定@click实现点击事件。
<!-- 主要按钮 -->
<el-button type="primary">添加任务</el-button>
<!-- 文本按钮、普通按钮 -->
<el-button plain>删除</el-button>
-
表格组件 el-table
用于批量展示列表数据,通过:data绑定响应式数组;<el-table-column>定义列,prop对应数据字段,label为列名。
支持作用域插槽#default,在操作列自定义按钮、逻辑;
搭配stripe属性可实现斑马纹表格,提升视觉效果。 -
弹窗组件 el-dialog
弹出层组件,通过v-model双向绑定布尔值控制显示/隐藏;可自定义标题、宽度,内置底部插槽放置「确定/取消」按钮。
本案例中用于删除二次确认,避免误操作。 -
表单系列组件(el-form / el-form-item / el-input / el-select)
el-form:外层表单容器,通过:model绑定表单数据对象;el-form-item:表单项,搭配label设置文本描述;el-input:输入框,使用v-model实现双向数据绑定,支持普通输入、文本域;el-select+el-option:下拉选择器,用于固定选项选择(如本案例选择星期)。
- 消息提示 ElMessage
全局方法,调用后弹出轻量级提示框,用于操作反馈(删除成功、添加成功),提升交互体验。
(四)表单基础校验(今日重点)
为表单添加校验规则,约束用户输入内容,保证数据合法性:
- 在
el-form标签通过:rules绑定校验规则对象; - 规则可配置非空校验、字符长度校验等;
- 提交表单前调用表单实例的校验方法,校验通过再执行业务逻辑。
(五)结合前三天知识点综合运用
- 响应式数据:使用
reactive定义任务列表、表单数据,ref控制弹窗、页面显隐状态; - 组件拆分:拆分为根组件、表格展示组件、新增表单组件,遵循组件化思想;
- 组件通信
props:父组件向子组件传递任务列表数据;- 自定义事件
defineEmits:子组件触发事件,向父组件传递新增/删除的数据,实现跨组件数据修改。
三、实战案例:学习任务管理平台
- 项目结构
App.vue(根组件):管理全局任务数据、分发数据、监听子组件事件,控制页面切换;Task.vue(表格组件):渲染任务表格,弹窗确认删除,触发删除事件;AddTask.vue(新增表单组件):搭建新增任务表单,选择星期、填写内容,提交/取消并向上传递事件。
- 核心功能实现
- 数据展示:根组件用
reactive初始化四天学习任务数据,通过props传给表格组件,el-table循环渲染; - 删除功能:点击表格删除按钮 → 弹出确认弹窗 → 确认后子组件触发自定义事件,父组件通过
splice删除对应数据,弹出成功提示; - 新增功能:点击「添加任务」切换至表单页面,填写表单并选择星期,提交后表单组件向上传递数据,父组件自动生成自增 ID 并追加到列表;
- 页面切换:使用
ref定义布尔变量,搭配v-show实现「表格页面」和「新增表单页面」的切换。
- 遇到的问题与解决
- 组件样式/标签不生效:忘记在入口文件引入 Element Plus 样式,补充
index.css引入后恢复正常; - 父子组件事件失效:自定义事件命名前后不统一,统一命名规则后事件正常触发;
- ID 重复问题:新增任务时读取列表最后一条数据的 ID,做自增处理,保证 ID 唯一。
四、今日总结
- Element Plus 大幅简化 UI 开发,核心记住全局引入 +
el-前缀组件两大要点; - 表格、弹窗、表单是后台系统高频组件,需熟练掌握绑定数据、插槽、事件用法;
- 表单校验是表单开发必备能力,可规范用户输入,提升项目健壮性;
- 本次案例串联了前四天所有知识点:Vue 基础语法、响应式、组件拆分、父子组件通信,实现了纯前端增删查交互,完整掌握 Vue 3 基础 + 组件库的联合开发模式。
联系任务代码:
<script setup lang="ts">
import {reactive,ref} from 'vue'
import Task from './Task.vue';
import AddTask from './AddTask.vue';
import { ElMessage } from 'element-plus'
const taskList = reactive([
{ id: 1, day: "周一", name: "Vue基础", content: "模板语法、响应式" },
{ id: 2, day: "周二", name: "组件开发", content: "组件拆分、复用" },
{ id: 3, day: "周三", name: "组件通信", content: "Props、自定义事件" },
{ id: 4, day: "周四", name: "ElementPlus", content: "组件、表单、表格" }
])
//收到子组件的事件后删除对应任务
function deleteTask(id:number){
console.log('父组件收到子组件调用,id:'+id)
const index = taskList.findIndex(item =>item.id===id)
if(index!==-1){
taskList.splice(index,1)
}
console.log(taskList)
ElMessage.success('任务删除成功!')
}
let showData=ref(true)
function changeShowData(){
showData.value=!showData.value
}
function addTask(form:any){
console.log(form)
const lastTask = taskList.at(-1)?.id
const data=form
if(lastTask){
data.id=lastTask+1
}
console.log(data)
taskList.push(data)
changeShowData()
ElMessage.success('任务添加成功!')
}
</script>
<template>
<div class="ticks">
<h3>
学习任务管理平台
</h3>
<el-divider />
<el-button type="primary" @click="changeShowData" v-show="showData">添加学习任务</el-button>
<Task :task="taskList" @deleteTask="deleteTask" v-show="showData"></Task>
<!-- ✅ 正确:使用短横线命名法,修正拼写 -->
<AddTask
@add-task="addTask"
@cancel-add-task="changeShowData"
v-show="!showData"
></AddTask>
</div>
</template>
<style>
h3{
text-align: center;
}
</style>
<script setup lang="ts">
import { ref } from 'vue'
const data=defineProps(['task'])
const values=data.task
console.log(data.task)
const emit=defineEmits(["deleteTask"])
function deleteTask(id:number){
console.log(id)
emit('deleteTask',id)
dialogVisible.value = false
}
const dialogVisible = ref(false)
const currentRow = ref<any>(null)
// 打开删除弹窗
function openDialog(row:any) {
console.log("当前删除---")
currentRow.value = row // 把当前行存起来
console.log(currentRow.value)
dialogVisible.value = true
}
</script>
<template>
<div>
<el-table :data="values" stripe style="width: 100%">
<el-table-column prop="id" label="排序" width="100"/>
<el-table-column prop="day" label="星期" />
<el-table-column prop="name" label="名称" />
<el-table-column prop="content" label="内容" />
<el-table-column label="操作" width="200">
<template #default="scope">
<el-button plain @click="openDialog(scope.row)" type="primary">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<el-dialog
v-model="dialogVisible"
title="确定删除吗"
width="500"
v-show="dialogVisible"
>
<span>{{currentRow?.name}}</span>
<template #footer>
<div class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="deleteTask(currentRow.id)">
确定
</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<style>
</style>
<script setup lang="ts">
import { reactive, ref } from 'vue'
import type { FormInstance, FormRules } from 'element-plus'
// 表单 ref(用于校验)
const ruleFormRef = ref<FormInstance>()
// ✅ 只用一个表单对象!!!
const form = reactive({
name: '',
day: '',
content: '',
})
// 校验规则
const check = (rule: any, value: any, callback: any) => {
if (!value) {
return callback(new Error('此字段不能为空'))
}
callback()
}
const rules = reactive<FormRules<typeof form>>({
name: [{ validator: check, trigger: 'blur' }],
day: [{ validator: check, trigger: 'change' }],
content: [{ validator: check, trigger: 'blur' }],
})
// 事件
const emit = defineEmits<{
addTask: [task: typeof form]
cancelAddTask: []
}>()
// ✅ 提交时必须先校验!
const onSubmit = async () => {
if (!ruleFormRef.value) return
// 校验通过才提交
await ruleFormRef.value.validate((valid) => {
if (valid) {
emit('addTask', { ...form })
}
})
}
// 取消
const cancel = () => {
emit('cancelAddTask')
}
</script>
<template>
<div>
<h5>新增学习任务</h5>
<!-- ✅ 绑定正确的 model + ref + rules -->
<el-form
ref="ruleFormRef"
:model="form"
:rules="rules"
label-width="auto"
style="max-width: 600px"
>
<!-- ✅ 必须加 prop -->
<el-form-item label="任务名称" prop="name">
<el-input v-model="form.name" />
</el-form-item>
<el-form-item label="星期" prop="day">
<el-select v-model="form.day" placeholder="选择星期几">
<el-option label="星期一" value="周一" />
<el-option label="星期二" value="周二" />
<el-option label="星期三" value="周三" />
<el-option label="星期四" value="周四" />
<el-option label="星期五" value="周五" />
<el-option label="星期六" value="周六" />
<el-option label="星期日" value="周日" />
</el-select>
</el-form-item>
<el-form-item label="学习内容" prop="content">
<el-input v-model="form.content" type="textarea" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">确定</el-button>
<el-button @click="cancel">取消</el-button>
</el-form-item>
</el-form>
</div>
</template>
更多推荐


所有评论(0)