第1次 · 搭建第一个 Vue 3 工程并跑通 Element Plus 页面
第1次 · 搭建第一个 Vue 3 工程并跑通 Element Plus 页面
第1/7页 · 先知道今天要做什么
今天只做一件看得见的事:在自己电脑上建起一个 Vue 3 工程,把脚手架的默认首页换成一个“学员信息管理”页面。
今天的场景
学校要统计每个班的学员信息,以前靠纸笔登记,改一次要重抄一张表。现在换一种做法:网页上一张表格列出所有学员,搜索框里输入学号就只剩那一个人,点“新增学员”弹出窗口填资料,填完表格立刻多出一行。
这个页面从头到尾只有两个文件在起作用:一个 App.vue,一个 main.js。今天要做的,就是把 App.vue 从脚手架的欢迎页,换成这张能用的学员表。
下课时拿出这三样结果
| 做到什么 | 在哪里看 | 完成的证据 |
|---|---|---|
| 工程能跑起来 | 浏览器 http://localhost:5173 |
终端显示 VITE ready,浏览器打开后不再是 Vue 欢迎页,而是你粘进去的学员表。 |
| Element Plus 组件正常显示 | 浏览器页面 | 表格有边框和斑马纹,按钮是蓝色圆角,状态列是彩色小标签,不是纯文本。 |
| 数据能跟着操作变化 | 搜索框与新增弹窗 | 输入学号能实时过滤;新增一条后表格末尾立即出现新行并弹出绿色成功提示。 |
你只需要带着这些基础来
会写最基本的 JavaScript:let/const 声明变量、箭头函数、数组的 push 和 filter;能看懂常见 HTML 标签(div、h2、button)。不需要提前学过 Vue。
本课时 45 分钟怎么上
| 时间 | 老师带着做 | 学生留下什么 |
|---|---|---|
| 0—8 分钟 | 演示最终效果,说明今天只用两个文件。演示 npm run dev 与热更新(改一个字保存,浏览器自动变)。 |
知道今天的目标页面长什么样。 |
| 8—20 分钟 | 一步步执行 npm create vue@3.12.0,逐个解释每个交互提问该怎么选。 |
自己电脑上出现一个能启动的空白工程。 |
| 20—30 分钟 | 安装 element-plus,讲解“为什么装完还要引 CSS”,把本课 App.vue 整段粘贴进去。 |
页面成功从欢迎页变成学员表。 |
| 30—40 分钟 | 讲清三个核心:ref 让数据变成响应式、v-model 双向绑定、el-table 用 prop 取字段。学生改成自己的学号姓名。 |
表格里有自己真实的一条记录。 |
| 40—45 分钟 | 巡视解决白屏、端口占用、样式丢失三类问题;抽查学生说出“哪个变量控制弹窗”。 | 全员跑通并提交。 |
从哪里开始
在机房电脑或自己的笔记本上,先用终端确认装好了 Node.js:
- 打开终端(Windows 用 PowerShell,macOS 用“终端”),输入
node -v回车。 - 只要能看到形如
v20.11.0、v22.9.0的版本号即可;本课程要求 Node 18 及以上。 - 如果提示“不是内部或外部命令”,先安装 Node.js 的 LTS 版本,重开终端再试。
今天先掌握到这里
今天只要求跑通,不要求全部看懂。核心是记住三件事:工程靠 npm run dev 启动、页面在 src/App.vue 里、Element Plus 的组件以 <el- 开头。
ref 为什么必须写 .value、computed 怎么用、组件之间怎么传数据,从第 3 课开始逐个讲。
来源:本课自编 Vue 3 前端核心技能实训 · 语法依据 Vue 3.5 官方文档 · 组件依据 Element Plus 2.8 官方文档
第2/7页 · 把新词说清楚
先把本课出现的名字认清,看到名字时回到真实文件定位。
新词与本课含义
| 名字 | 用熟悉的话理解 | 本课里长什么样 |
|---|---|---|
| Node.js | 让 JavaScript 能脱离浏览器、直接在电脑上运行的运行环境。前端的“编译器”和“包管理器”都跑在它上面。 | 终端里 node -v 打印出来的那个版本号。 |
| npm | Node 自带的包管理器,负责下载和安装别人写好的代码库。 | npm install element-plus 这条命令。 |
| Vite | 开发服务器与打包工具。启动后它盯着你的文件,改一处就立刻推给浏览器。 | 终端里的 npm run dev,以及 vite.config.js。 |
| SFC(单文件组件) | 把一个组件的“结构、逻辑、样式”写进同一个 .vue 文件。 |
src/App.vue 里的 <template> / <script setup> / <style> 三段。 |
<script setup> |
Vue 3 的语法糖。在这里声明的变量和函数,模板里可以直接用,不用手动 return。 |
<script setup> 里 const keyword = ref(''),模板里直接写 keyword。 |
ref() |
响应式包裹器。把普通数据包成“一变就通知页面刷新”的对象。JS 里读写要加 .value,模板里直接写名字。 |
const students = ref([...]) |
| Element Plus | 一套现成的 Vue 3 组件库,按钮、表格、弹窗、提示都是配好的,不用自己写 CSS。 | <el-button type="primary">新增学员</el-button> |
v-model |
双向绑定指令。输入框内容变,变量跟着变;代码里改变量,输入框也跟着变。 | <el-input v-model="keyword" /> |
三个新建目录的对照关系
执行完脚手架命令后,工程里会出现这些名字,先把它们对上位置:
| 名字 | 真实位置 | 干什么用的 |
|---|---|---|
package.json |
工程根目录 | 记录依赖清单和 npm run dev 对应的命令。 |
index.html |
工程根目录 | 浏览器真正打开的那个 HTML,里面只有一个空的 <div id="app">。 |
src/main.js |
src/ |
入口文件。它引入 App.vue,再把它挂到 #app 上。 |
src/App.vue |
src/ |
今天唯一要改的文件,根组件。 |
src/assets/main.css |
src/assets/ |
脚手架自带的默认样式,会把页面挤成两栏,今天要清空它。 |
vite.config.js |
工程根目录 | Vite 的配置,本课不动它。 |
把名字分清
- Vue 是框架,Element Plus 是组件库,Vite 是工具。三者不是一个东西:Vue 负责“数据变、页面变”,Element Plus 负责“长得好不好看”,Vite 负责“怎么跑起来、怎么打包”。
ref是 Vue 提供的函数,students是我们自己起的变量名。别把函数名当数据名。<el-table>是整张表,<el-table-column>是其中一列。表负责容器和滚动,列负责取哪一份数据、显示什么表头。prop是“属性名”,写的是数据对象的 key,大小写敏感。数据里叫username,这里就不能写userName。
本课只用八个组件与 API
| 组件 / API | 什么时候用 | 达到的效果 |
|---|---|---|
<el-table :data="students"> |
展示多行学员 | 自动渲染带边框和斑马纹的表格。 |
<el-table-column> |
配置每一列 | 用 prop 直接取字段,或用插槽自定义内容。 |
<el-input v-model="keyword"> |
输入搜索关键词 | 边打字边过滤,不用按回车。 |
<el-button type="primary"> |
触发新增 | 蓝色主按钮,一眼看出是主操作。 |
<el-tag type="success"> |
显示状态 | 彩色小徽章,比纯文字更醒目。 |
<el-dialog v-model="visible"> |
弹出录入窗口 | 居中遮罩弹窗,含确定/取消。 |
<el-form> + <el-form-item> |
组织录入项 | 标签和输入框自动对齐。 |
ElMessage.success() |
操作后轻提示 | 页面顶部滑出绿色提示条,3 秒后消失。 |
只看这三行:数据是怎么自动送到表格上的
<!-- 1. JS 里准备一个响应式数组 -->
const students = ref([
{ id: 1, username: '2510101', name: '小林', major: '软件工程' }
])
<!-- 2. 模板里交给 el-table,用 prop 指明取值字段 -->
<el-table :data="students" border stripe>
<el-table-column prop="username" label="学号" width="140" />
<el-table-column prop="name" label="姓名" width="120" />
<el-table-column prop="major" label="专业" />
</el-table>
按位置一一对应
| 模板里的写法 | 对应 JS 里的什么 | 网页上看到什么 |
|---|---|---|
:data="students" |
响应式数组变量 students |
整张表的数据来源 |
prop="username" |
每个对象的 item.username |
每一行的学号格 |
prop="name" |
每个对象的 item.name |
每一行的姓名格 |
label="学号" |
静态文本 | 表头那一格的标题 |
先口头预测
如果在 JS 里执行这样一行:
students.value.push({ id: 4, username: '2510104', name: '小张', major: '大数据' })
网页上需要我们写 document.createElement('tr')、再手动 appendChild 吗?
完全不需要。 Vue 监听到 students 变了,自动在表尾补一行,Element Plus 自动把样式套上去。这就是数据驱动视图——你只管改数据,页面自己跟上。
来源:本课自编 Vue 3 前端核心技能实训 · 语法依据 Vue 3.5 官方文档 · 组件依据 Element Plus 2.8 官方文档
第3/7页 · 先看一个小例子
先看本课的最终成果:一份完整的 App.vue。它已经包含了表格、搜索、新增弹窗和删除确认,是本课第 5 页要粘进工程的那一份。
完整代码:App.vue
<script setup>
import { ref, computed } from 'vue'
import {
ElButton, ElInput, ElTable, ElTableColumn, ElTag, ElDialog,
ElForm, ElFormItem, ElSelect, ElOption, ElMessage, ElMessageBox
} from 'element-plus'
import 'element-plus/dist/index.css'
const title = ref('班级学员信息管理')
const students = ref([
{ id: 1, username: '2510101', name: '小林', major: '软件工程', status: '在读' },
{ id: 2, username: '2510102', name: '张伟', major: '大数据技术', status: '在读' },
{ id: 3, username: '2510103', name: '王芳', major: '软件工程', status: '请假' }
])
const keyword = ref('')
const dialogVisible = ref(false)
const form = ref({ username: '', name: '', major: '软件工程', status: '在读' })
const filteredStudents = computed(() => {
const kw = keyword.value.trim().toLowerCase()
if (!kw) return students.value
return students.value.filter(
s => s.username.toLowerCase().includes(kw) || s.name.toLowerCase().includes(kw)
)
})
const openDialog = () => {
form.value = { username: '', name: '', major: '软件工程', status: '在读' }
dialogVisible.value = true
}
const submitForm = () => {
if (!form.value.username.trim() || !form.value.name.trim()) {
ElMessage.warning('学号与姓名不能为空')
return
}
if (students.value.some(s => s.username === form.value.username.trim())) {
ElMessage.error(`学号 ${form.value.username} 已存在`)
return
}
const nextId = students.value.length ? Math.max(...students.value.map(s => s.id)) + 1 : 1
students.value.push({
id: nextId,
username: form.value.username.trim(),
name: form.value.name.trim(),
major: form.value.major,
status: form.value.status
})
ElMessage.success(`学员 ${form.value.name} 录入成功`)
dialogVisible.value = false
}
const removeStudent = (row) => {
ElMessageBox.confirm(`确定移除【${row.name}(${row.username})】吗?`, '删除确认', {
confirmButtonText: '确定删除',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
students.value = students.value.filter(s => s.id !== row.id)
ElMessage.success('已移除该学员')
}).catch(() => {})
}
</script>
<template>
<div class="page">
<div class="toolbar">
<h2 class="page-title">🎓 {{ title }}</h2>
<el-button type="primary" @click="openDialog">+ 新增学员</el-button>
</div>
<div class="filter-bar">
<el-input v-model="keyword" placeholder="输入学号或姓名搜索" clearable style="width: 260px" />
<el-tag type="info" size="large">共 {{ filteredStudents.length }} 人</el-tag>
</div>
<el-table :data="filteredStudents" border stripe style="width: 100%">
<el-table-column prop="id" label="序号" width="70" align="center" />
<el-table-column prop="username" label="学号" width="140" />
<el-table-column prop="name" label="姓名" width="120" />
<el-table-column prop="major" label="专业" />
<el-table-column label="状态" width="110" align="center">
<template #default="scope">
<el-tag :type="scope.row.status === '在读' ? 'success' : 'warning'">
{{ scope.row.status }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="100" align="center">
<template #default="scope">
<el-button type="danger" size="small" link @click="removeStudent(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-dialog v-model="dialogVisible" title="录入新学员" width="450px">
<el-form label-width="80px">
<el-form-item label="学号">
<el-input v-model="form.username" placeholder="如 2510101" />
</el-form-item>
<el-form-item label="姓名">
<el-input v-model="form.name" placeholder="学员姓名" />
</el-form-item>
<el-form-item label="专业">
<el-input v-model="form.major" placeholder="如 软件工程" />
</el-form-item>
<el-form-item label="状态">
<el-select v-model="form.status" style="width: 100%">
<el-option label="在读" value="在读" />
<el-option label="请假" value="请假" />
</el-select>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="submitForm">确认保存</el-button>
</template>
</el-dialog>
</div>
</template>
<style>
/* 覆盖 create-vue 脚手架默认样式,保证本文件单独粘贴后即可正常铺满页面 */
html, body, #app {
margin: 0;
padding: 0;
max-width: none;
width: auto;
display: block;
text-align: left;
background: #f5f7fa;
}
</style>
<style scoped>
.page { max-width: 1000px; margin: 24px auto; padding: 24px; background: #fff; border-radius: 8px; box-shadow: 0 2px 12px rgba(0, 0, 0, .06); }
.toolbar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 18px; }
.page-title { margin: 0; font-size: 20px; color: #303133; }
.filter-bar { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
</style>
预期看见什么
打开 http://localhost:5173 后:
- 页面中央有一张白色卡片,卡片左上角是“🎓 班级学员信息管理”,右上角是蓝色“+ 新增学员”按钮。
- 表格里有 3 行初始数据。“在读”显示浅绿色徽章,“请假”显示淡黄色徽章。
- 在搜索框输入
小,表格只剩两行(小林、小张不存在——只有“小林”匹配),清空后恢复三行。 - 点“新增学员”,弹出居中对话框;填完点“确认保存”,顶部滑出绿色提示,表格末尾多出一行。
- 点某一行的“删除”,弹出确认框;点“取消”数据还在,点“确定删除”该行消失。
先猜一猜,读完代码再回答
代码里 el-table 绑的是 :data="filteredStudents",不是 :data="students"。那新增一条学员后,为什么还能看到他?
因为 filteredStudents 是用 computed 算出来的:它内部读的是 students。students 一变,Vue 自动重算 filteredStudents,表格跟着更新。如果直接绑 students,搜索框就失效了——这正是第 4 课要展开的内容。
来源:本课自编 Vue 3 前端核心技能实训 · 语法依据 Vue 3.5 官方文档 · 组件依据 Element Plus 2.8 官方文档
第4/7页 · 一步一步做出来
本页先把工程搭起来。每一步都给出“输入什么、看到什么”,对不上就停下来按第 6 页排查。
第1步:确认 Node 环境
在终端执行:
node -v
npm -v
预期:两行版本号,例如 v22.9.0 和 10.9.0。
对不上:提示命令不存在,说明 Node 未安装或未加入 PATH。去 Node.js 官网下载 LTS 版安装,安装完关闭并重新打开终端再试。
第2步:创建工程
在你打算放代码的目录下执行(例如 D:\code 或 ~/code):
npm create vue@3.12.0
之后会连续出现几个提问,逐个按下面这样选(用方向键移动,回车确认):
| 提问 | 选什么 | 为什么 |
|---|---|---|
Project name |
输入 lesson-vue-01 |
工程目录名,用英文,不要有空格和中文。 |
Add TypeScript? |
No |
本课程用 JavaScript,语法更直观。 |
Add JSX Support? |
No |
用不到。 |
Add Vue Router ...? |
No |
第 28 课才用,那时再单独装。 |
Add Pinia ...? |
No |
第 26 课才用,那时再单独装。 |
Add Vitest ...? |
No |
单元测试第 45 课讲。 |
Add an End-to-End Testing Solution? |
No |
同上。 |
Add ESLint ...? |
Yes |
建议开启,能提前发现写错的变量名。 |
Add Prettier ...? |
No |
可选。 |
预期:终端显示 Scaffolding project in ...lesson-vue-01...,并列出 Done. Now run: 后面几条命令。
第3步:安装依赖并首次启动
cd lesson-vue-01
npm install
npm run dev
预期:终端输出类似
VITE v5.x.x ready in 400 ms
➜ Local: http://localhost:5173/
按住 Ctrl 点这个地址(或手动复制到浏览器),能看到 Vue 默认欢迎页。
热更新验证:回到编辑器把
App.vue里You did it!改成我改的,保存。不用重启,浏览器应当立刻变化。这就是 Vite 的价值。
第4步:安装 Element Plus
先按 Ctrl + C 停掉开发服务器,然后:
npm install element-plus
预期:终端出现 added N packages in Xs,同时 package.json 的 dependencies 里多出 "element-plus": "^2.8.x"。
为什么要装两次:npm install 装的是脚手架自己声明的依赖;Element Plus 不是默认依赖,必须显式再装一次。
第5步:清空脚手架默认样式
脚手架自带 src/assets/main.css,它会把 #app 变成两栏网格、给 body 加倍居中,表格放进去会错位。
打开 src/assets/main.css,全选删除,保存为空白文件。
(本课 App.vue 末尾也带了一段兼容样式,即使忘了清也能正常显示;正式项目里建议直接清空,保持单一来源。)
第6步:替换 App.vue
把第 3 页那份完整代码,整段覆盖 src/lesson-vue-01/src/App.vue。保存后:
npm run dev
重新打开 http://localhost:5173,应当看到学员信息表。
本课工程目录速查
| 工程内路径 | 本次作用 |
|---|---|
src/App.vue |
要修改的文件,整段覆盖。 |
src/assets/main.css |
清空(第 5 步)。 |
src/main.js |
不改动。本课 App.vue 自己 import 了 Element Plus,不依赖它。 |
index.html |
不改动。 |
package.json |
只查看,确认 element-plus 已写入。 |
本课怎样运行:npm run dev
- 在工程根目录(含
package.json的那一层)打开终端。 - 执行
npm run dev,等出现Local: http://localhost:5173/。 - 浏览器访问该地址。改代码保存后浏览器自动刷新;报错看浏览器控制台(F12 → Console)和终端两处。
- 用完按
Ctrl + C停止服务,释放 5173 端口。
完成修改后检查
| 操作或输入 | 预期观察 |
|---|---|
| 浏览器打开 5173 | 显示学员表,而不是 Vue 欢迎页。 |
搜索框输入 2510101 |
表格只剩小林这一行。 |
| 点击“+ 新增学员” | 弹出居中对话框,四个字段可输入。 |
终端 npm run dev 后改一个字 |
浏览器自动更新,无需手动刷新。 |
来源:本课自编 Vue 3 前端核心技能实训 · 语法依据 Vue 3.5 官方文档 · 组件依据 Element Plus 2.8 官方文档
第5/7页 · 换成自己的代码
前面的代码看懂多少先放下,这一页必须亲手做完。
你的任务
- 换成自己的信息:把
students数组里第一条记录改掉,username填自己的真实学号,name填自己的名字,major填自己真实的专业。保存后确认浏览器第一行变了。 - 新增一条真实记录:点“+ 新增学员”,录入你自己的信息,状态选“在读”,保存。确认表格末尾出现新行,且顶部弹出绿色提示。
- 扩展状态颜色:给状态多一种取值
预警。要求:在读用绿色(type="success")、请假用黄色(type="warning")、预警用红色(type="danger")。 提示:把:type的值从三元表达式改成一个函数调用,例如:type="statusType(scope.row.status)",然后在<script setup>里写这个函数。 - 验证系统会不会拦你:故意录入一个和表格里重复的学号,确认弹出红色错误提示且表格没变化;再点你自己那行的“删除”,在确认框里点“取消”,确认数据没被删掉。
按这张操作单完成
| 步骤 | 打开哪个文件、改哪里 | 运行后应该看到什么 |
|---|---|---|
| 1 启动基线 | 终端 npm run dev |
浏览器打开学员表,初始 3 行。 |
| 2 改自己那行 | src/App.vue 里 students 数组第一条 |
第一行显示你自己的学号与姓名。 |
| 3 新增自己 | 页面点【+ 新增学员】 | 绿色提示弹出,表格末尾新增一行。 |
| 4 搜索定位 | 搜索框输入自己的学号 | 只剩你这一行。 |
| 5 三色徽章 | 改状态列的 :type,加一个 statusType 函数 |
预警 显示红色徽章。 |
| 6 防误删测试 | 点自己那行【删除】→ 弹窗点【取消】 | 提示已取消,数据仍在。 |
参考改法:三色徽章
在 <script setup> 里新增:
const statusType = (status) => {
if (status === '在读') return 'success' // 绿
if (status === '请假') return 'warning' // 黄
return 'danger' // 红,兜底
}
模板里把那一行改成:
<el-tag :type="statusType(scope.row.status)">{{ scope.row.status }}</el-tag>
再往 el-select 里加一项:
<el-option label="预警" value="预警" />
最低完成标准:先把这三项做实
| 检查项 | 通过条件 |
|---|---|
| 页面跑通 | 浏览器能打开学员表,样式正常(按钮是蓝的、表格有边框)。 |
| 有自己的数据 | 表格里能看到你自己的真实学号与姓名。 |
| 交互可用 | 搜索能过滤、新增能插入、删除有确认且取消有效。 |
在本地写练习记录
在工程根目录新建 练习记录.md,写下:
- 你的学号、姓名,以及
npm create vue@3.12.0时每个提问你选了什么。 - 第 5 页四项任务逐条写“操作 / 预期 / 实际结果”;没做通就写“未完成,卡在哪一句报错”。
- 抄下
students数组第一条和状态列那一行的最终代码。
最后交什么
提交 src/App.vue 和 练习记录.md 两个文件。不需要提交 node_modules(体积大且可以随时重装)。
来源:本课自编 Vue 3 前端核心技能实训 · 语法依据 Vue 3.5 官方文档 · 组件依据 Element Plus 2.8 官方文档
第6/7页 · 出错时从哪里查
先保留现象,一次只改一处,改完重跑确认。
把现象和检查动作对上
| 看到什么现象 / 报错 | 先检查哪里 | 修好后怎样确认 |
|---|---|---|
| 浏览器打开是白屏 | 按 F12 看 Console 第一条红字。多数是 App.vue 粘贴不完整,<template> 或多了一层大括号。 |
红字消失,页面出现表格。 |
终端报 EADDRINUSE: address already in use :::5173 |
5173 端口被上次没关的服务占着。按 Ctrl + C 关掉旧终端,或改用 npm run dev -- --port 5174。 |
终端打印新的 Local: 地址并能打开。 |
| 页面只有文字,按钮是方的、表格没边框 | 没引入 Element Plus 的 CSS。检查 <script setup> 里有没有 import 'element-plus/dist/index.css'。 |
圆角蓝色按钮、斑马纹表格恢复。 |
Console 报 Failed to resolve component: el-button |
组件名没被识别。检查顶部 import { ElButton } from 'element-plus' 是否写成 el-button(import 时用大驼峰)。 |
警告消失,按钮渲染出来。 |
Cannot read properties of undefined (reading 'value') |
某个 ref 没写初始值,或者模板里对 JS 变量误加了 .value。 |
保证 ref('') 有初始值,报错消失。 |
| 表格列是空的,有行没字 | 该列 prop 和数据的 key 不匹配(username 写成 userName)。 |
改一致后文字出现。 |
| 新增后表格不刷新 | 在 <script setup> 里对数组用了重新赋值却没走响应式,或搜索框残留了关键词导致被过滤掉。检查 students.value.push(...) 写法、并清空搜索框。 |
清空搜索后新行出现。 |
npm install 卡住或超时 |
网络到 npm 官方源不通。换国内镜像:npm config set registry https://registry.npmmirror.com 后重试。 |
安装完成并出现 added N packages。 |
排错口诀
白屏先看控制台第一条红字; 样式全丢查 Element Plus 的 CSS; 组件不认看 import 是否大驼峰; 表格空白对准
prop,弹窗不出查v-model。
不要用这些办法“修复”
- 表格不更新时,不要用
location.reload()刷新整页来掩盖问题,要查清楚是哪个响应式变量没变。 - 组件样式不对时,不要给每个标签狂加
style="color:red",优先用 Element Plus 的type、size属性。 - 报错看不懂时,不要盲目注释掉整段代码,先只保留报错那几行,缩小范围。
需要老师帮忙时交这些
工程目录名;你改动的文件路径(src/App.vue);浏览器 Console 第一条红色错误的原文;终端里的完整报错;你期望看到什么、实际看到什么。截图之外请保留错误文字。
老师巡视时只问三句话
- 哪个变量控制弹窗显示?它在哪一行定义的?(能指出
const dialogVisible = ref(false)) - 表格这一列是通过哪个
prop取值的?(能指出prop="username"与数据 key 的对应) - 你新加的那条记录,除了页面还能在哪里看到?(能在
<script setup>的students数组里指出它)
来源:本课自编 Vue 3 前端核心技能实训 · 语法依据 Vue 3.5 官方文档 · 组件依据 Element Plus 2.8 官方文档
第7/7页 · 用自己的话讲一遍
用真实文件和本机结果说明你完成了什么;先说动作,再说术语。
回到第 3 页:你刚才猜对了吗?
:data="filteredStudents" 而不是 students,为什么新增后仍能看到新数据?
参考解释:filteredStudents 是用 computed 从 students 算出来的。它读 students 时建立了依赖关系;students 一变,Vue 自动重算它,表格也就跟着变。绑 filteredStudents 的好处是搜索和展示用同一个数据源,不会出现“搜到一半新增看不见”的错乱。
回答本课的两个问题
| 问题 | 参考解释 |
|---|---|
为什么 npm install 之后还要单独 npm install element-plus? |
npm install 只装 package.json 里已经写好的依赖;Element Plus 不在脚手架默认清单里,必须显式安装才会被下载。 |
| 为什么改一个字浏览器就变了,不用重启? | 跑着的是 Vite 开发服务器,它监听文件变化,改完立刻通过模块热替换推给浏览器,只重载变化的那部分。 |
五个必须能答上来的问题
| 考考自己 | 可以这样通俗回答 |
|---|---|
ref() 是干什么的?普通变量不行吗? |
普通变量变了,浏览器根本不知道;被 ref() 包起来后 Vue 会盯着它,一变就更新页面。 |
为什么 JS 里要写 students.value.push()? |
因为 ref() 返回的是一个带 .value 的包装对象,真正的数组在 .value 里面。模板里 Vue 会自动拆包,所以只写 students。 |
v-model 省掉了什么代码? |
省掉了手动监听 input 事件、再读 e.target.value 赋值的两步,输入和变量自动双向同步。 |
el-table 的 prop 是什么? |
就是“属性名”,告诉这一列去数据对象的哪个字段取值。 |
#default="scope" 插槽什么时候用? |
当这一列不想只显示纯文本,而要显示彩色标签或按钮时,用 scope.row 拿到当前这一行的完整对象再自己排版。 |
一分钟现场演示指南
- 展示界面:浏览器打开 5173,指着表格说:“这是用 Element Plus 渲染的学员列表,包含学号、姓名、专业和带颜色的状态徽章。”
- 演示新增:点【+ 新增学员】,填自己的真实学号姓名,保存。指出顶部绿色提示和表格末尾新增的行。
- 演示筛选:搜索框输入自己的名字,说明表格瞬间只剩一行;清空后全量恢复。强调“没有写一行刷新代码”。
- 演示确认:点删除,展示二次确认框,点取消,说明“防御机制生效,数据没被误删”。
交作业前最后检查
src/App.vue与练习记录.md已保存。- 删掉代码里所有真实密码、token;本课不需要任何账号信息。
- 确认终端
npm run dev能一次启动成功,再提交。
课后再做一个小对照
把 students 的初始数组改成 4 条,其中一条状态填 预警,其余不动。保存后确认表格出现 4 行、且红色徽章生效。写下:改了几个字符,页面哪一处跟着变了。
来源:本课自编 Vue 3 前端核心技能实训 · 语法依据 Vue 3.5 官方文档 · 组件依据 Element Plus 2.8 官方文档