ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Vue.js入门实战:从Vue 3响应式原理到Element Plus增删改查

Vue.js入门实战:从Vue 3响应式原理到Element Plus增删改查 上周有个刚入职的实习生跑来问我哥Vue.js 我看文档看了两周指令背得滚瓜烂熟真到写一个带表格的管理页面还是无从下手而且我的 Vue.js devtools (v5) 插件还打不开了调试全靠 console.log。这个问题太典型了几乎所有刚接触 Vue.js 的人都会卡在同一道坎上语法见了不少但脑子里没有一条完整的“从零到能干活”的路径。这篇文章我就按自己带新人的思路把 Vue.js 基础入门这件事重新捋一遍。从版本怎么选、环境装什么到响应式和组件化到底在讲什么再到用 Element Plus 半小时拼出一张能增删改查的表格最后专门聊聊热的那个问题——Vue.js devtools (v5) 插件为什么打不开了。整个过程不念文档只说人话给可以直接抄的代码和能落地的排查步骤。1. 开始之前的关键选择Vue 2、Vue 3、开发工具1.1 版本选型先搞清楚你学的是哪个 Vue现在一搜 Vue.js 教程能看到一半的旧文章在写 Vue 2 的 options API另一半新文章在写 Vue 3 的组合式 API。很多新手来回看几天直接精神分裂。我的建议非常简单没有任何旧项目负担的人直接学 Vue 3。Vue 2 官方维护实际上已经进入尾声生态里的新组件库也几乎都转向了 Vue 3。Element Plus 是 Element UI 的 Vue 3 版本组件名和用法大体一致但底层已经重写。你花两天学 Vue 2 语法再花几天把它迁移到 Vue 3 心智模型里不如一开始就落在 Vue 3 上。至于 Vue 2 的 options API 也不是完全没用公司维护老项目大概率会碰到但那属于“以后再说”的部分入门阶段别两头顾。从原理层面讲Vue 2 的响应式用的是Object.definePropertyVue 3 用的是Proxy。生活化的理解是Vue 2 像是给每个属性单独贴上监控标签新加一个属性就得手动贴一次Vue 3 是给整个对象安排了一个总监控室任何属性的增删改都逃不过它的眼睛。所以 Vue 3 里往响应式对象上直接新增属性、用数组下标改值都能正常触发更新这在 Vue 2 里是要踩坑的地方。1.2 环境准备装什么、装多新入门阶段环境不用复杂三样东西就够Node.js、一个包管理器、一个编辑器推荐 VSCode。Node.js 去官网下载 LTS 版本即可不用追最新版。装完之后在终端跑一下node -v和npm -v能看到版本号就说明基础环境通了。项目脚手架方面现在官方推荐的是create-vue也就是 Vite 底层的初始化工具。它比老一代的vue-cli轻量很多冷启动和热更新都明显更快。初始化命令是npm create vuelatest运行后会有几个交互问题新手建议只选 TypeScript 和 Router剩下的 Router、Pinia 这些如果暂时用不到可以全选 No后续需要了再加也不迟不要让额外的配置干扰初始学习。我平时带项目成员走这一步时会强调一个点不要把官方脚手架所有选项都打勾很多选项你看不懂等它生成一堆文件心里就只有四个字——我是谁。1.3 组件库选型Element UI 还是 Element PlusElement UI 是 Vue 2 时代的组件库Element Plus 是 Vue 3 时代的升级版。网上很多文章标题还挂着“Vue.js Element UI 入门”里面的代码直接搬进 Vue 3 项目多半跑不起来因为插槽语法、组件注册方式都有变化。如果你的项目是 Vue 3请毫不犹豫地装 Element Plusnpm install element-plus装好之后在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. Vue.js 核心机制拆解响应式、组件、生命周期2.1 响应式系统数据一变页面自己刷新的秘密初学 Vue.js 时最震撼的体验是JS 变量改了页面内容跟着变了我没操作过任何 DOM。这个效果就来自响应式系统。它做了一件关键的事把渲染和数据绑定成订阅关系。用生活场景打个比方你把手机号留在快递站新包裹一到快递员自动通知你。Vue 的响应式就是给每个被使用的数据装了一根电话线组件模板用到了哪个数据就自动成为这个数据的订阅者。数据变化时Vue 通知订阅者重新渲染页面就更新了。在 Vue 3 里声明响应式数据有两条路线// 组合式 API 写法推荐 import { ref, reactive } from vue const count ref(0) const user reactive({ name: 张三, age: 28 }) function addOne() { count.value user.age }ref管基本类型值在 script 里访问要写.value模板里直接用即可reactive管对象直接用属性访问。新手最容易犯的错是把ref放进reactive或者反过来嵌套然后页面不更新。其实规则很简单基本类型没有可监控的“形状”所以需要外面包一层.value对象本身结构清晰可以直接监控属性。刚开始用的时候宁可都用ref别在类型上消耗太多脑力const user ref({ name: 张三, age: 28 }) // script 里访问 user.value.name // 模板里直接写 user.name这种写法在组合式 API 里完全可以接受而且心智负担小是我给新手推荐的起步姿势。2.2 组件化开发像搭积木一样拼页面组件化是 Vue.js 的另一个基石思想。页面不是一整块 HTML而是把重复出现的区域拆成一块块积木最后拼装起来。弹窗是一个组件表格是一个组件搜索栏是一个组件。组件之间的关系分两种父子、独立。父子通信是入门必须掌握的核心就两句口诀父传子用 props子传父用 emit数据流向永远是单向的也就是单向数据流。为什么一定是单向的因为如果子组件能随意改父组件的数据一个页面二十个组件到处改同一份数据出问题时根本查不到是谁下的手。单向数据流保证所有变化都有迹可循这是工程化项目的安全线。一个最小父子通信示例!-- 父组件 -- template Child :titlepageTitle updatehandleUpdate / /template script setup import { ref } from vue import Child from ./Child.vue const pageTitle ref(首页) function handleUpdate(newTitle) { pageTitle.value newTitle } /script!-- 子组件 Child.vue -- template div{{ title }}/div button click$emit(update, 新的标题)改标题/button /template script setup defineProps({title: String}) defineEmits([update]) /script子组件里通过$emit把事件抛出去父组件监听后修改自己的数据页面再响应式更新。这个模式看起来很绕但它保证了“数据在哪个组件声明就在哪个组件修改”的规矩。2.3 模板指令把逻辑写进 HTML 的三种常用姿势模板语法是 Vue 最让人上手的部分因为它允许你在 HTML 标签上直接写逻辑。新手先掌握三个指令就够用v-if、v-for、v-model。v-if是“条件成立才渲染”适合用在权限判断、空状态展示上。v-for是列表渲染遍历一组数据生成重复结构。v-model是表单双向绑定本质是一个语法糖等于:value加input的缩写让你不必手动监听每一次输入。这里有一个高频问题必须提v-for一定要写:key。为什么Vue 的虚拟 DOM 在对比新旧列表时需要靠 key 来最小化更新范围。没有 key框架只能靠索引猜一旦列表中间插入或删除一项整个列表可能都被重新渲染甚至表单状态会错位到另一行。平时练习时用唯一值item.id没有 id 时用下标index兜底但要知道这只是临时方案生产环境建议补一个唯一字段。2.4 生命周期组件从创建到销毁的完整轨迹生命周期这个概念刚接触时很抽象我用开一家店打比方组件诞生前要准备店铺setup、挂招牌onMounted、营业中更新菜单onUpdated、最后关门盘库onUnmounted。理解这套时序很多问题就能想明白比如“为什么发请求要写在onMounted而不是模板里”。Vue 3 组合式 API 里最常用的两个周期钩子是onMounted和onUnmountedimport { onMounted, onUnmounted } from vue onMounted(() { // 页面渲染完成后执行请求数据、绑定原生事件、初始化第三方库 console.log(组件已经挂载到页面) }) onUnmounted(() { // 组件销毁前清理移除事件监听、清定时器 console.log(组件即将离开页面) })新手最容易忽略销毁前的清理。如果页面里挂了一个setInterval组件销毁后不去清掉定时器还在后台跑别的地方一刷新控制台啪叽冒出几个错误排查起来很费劲。所以我的习惯是任何全局性的监听和定时器都要在 onUnmounted 里还回去。3. 实操记录用 Vue 3 Element Plus 半小时做出一张完整管理页3.1 创建项目一条命令走完初始化理论说再多不如动手跑一遍。我按零基础路径重新走了一次下面这些步骤可以直接照抄。打开终端找个空目录执行npm create vuelatest my-vue-app过程中弹出的选项按以下思路选TypeScript先选 No或者选 Yes 但做好心理准备。入门阶段为了减去类型干扰选 No 更流畅JSX不需要NoRouter选 Yes因为做管理页面需要多路由时迟早要用Pinia先 No状态管理后面再学VitestNo单元测试以后再加项目生成后cd my-vue-app npm install npm run dev浏览器打开终端提示的本地地址看到官方欢迎页就说明项目骨架没问题。第一次跑通这个流程后你会发现 Vue.js 项目搭建本身并不神秘五个命令全是固定套路根本不需要记忆记个索引就行。3.2 接入 Element Plus全量引入和按需引入怎么选Element Plus 装好后接下来要决定怎么集成。全量引入最简单适合练习和内部管理系统npm install element-plus按需引入能显著减小打包体积。常见的做法是装官方推荐的自动导入插件npm install -D unplugin-vue-components unplugin-auto-import然后在 Vite 配置里加上这种插件注册// vite.config.js 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()] }) ] })按这种方式配置后你在模板里直接用el-button就行组件会被自动按需加载不需要手动 import 和注册。个人建议第一个项目老老实实用全量引入先解决功能问题等理解了打包体积是怎么回事再上自动导入不然配置出问题反而劝退。3.3 实现增删改查表格完整代码直接抄下面是一张最基础的“用户管理”页覆盖了表格渲染、新增、编辑、删除四个核心场景是管理后台最常见的骨架。新建src/views/UserManage.vue把代码贴进去。template div classuser-page div classtoolbar el-button typeprimary clickopenAdd新增用户/el-button /div el-table :datalist border stripe el-table-column propid labelID width80 / el-table-column propname label姓名 / el-table-column propage label年龄 width100 / el-table-column propcity label城市 / el-table-column label操作 width180 template #default{ row } el-button link typeprimary clickopenEdit(row)编辑/el-button el-button link typedanger clickhandleDelete(row)删除/el-button /template /el-table-column /el-table el-dialog v-modeldialogVisible :titleform.id ? 编辑用户 : 新增用户 width480 el-form :modelform label-width60px el-form-item label姓名 el-input v-modelform.name placeholder请输入姓名 / /el-form-item el-form-item label年龄 el-input-number v-modelform.age :min0 :max150 / /el-form-item el-form-item label城市 el-input v-modelform.city placeholder请输入城市 / /el-form-item /el-form template #footer el-button clickdialogVisible false取消/el-button el-button typeprimary clicksave保存/el-button /template /el-dialog /div /template script setup import { reactive, ref } from vue import { ElMessage, ElMessageBox } from element-plus const list ref([ { id: 1, name: 张三, age: 28, city: 上海 }, { id: 2, name: 李四, age: 32, city: 北京 } ]) const dialogVisible ref(false) const form reactive({ id: null, name: , age: null, city: }) function openAdd() { Object.assign(form, { id: null, name: , age: null, city: }) dialogVisible.value true } function openEdit(row) { Object.assign(form, row) dialogVisible.value true } function save() { if (!form.name || !form.city) { ElMessage.warning(请填写完整信息) return } if (form.id) { const index list.value.findIndex(item item.id form.id) list.value.splice(index, 1, { ...form }) ElMessage.success(修改成功) } else { list.value.push({ ...form, id: Date.now() }) ElMessage.success(新增成功) } dialogVisible.value false } function handleDelete(row) { ElMessageBox.confirm(确定删除用户「${row.name}」吗, 删除确认, { type: warning }) .then(() { list.value list.value.filter(item item.id ! row.id) ElMessage.success(删除成功) }) .catch(() {}) } /script这里有两处值得留意。第一list.value.splice(index, 1, { ...form })是编辑时推荐的替换方式它把整行对象替换掉而不是去修改form本身避免复用同一对象带来的脏数据问题。第二新增时用Date.now()生成临时 id只适用于纯前端演示真正接后端时应该由数据库返回用户 id。这段代码很小但它浓缩了几个核心知识点父组件维护数据列表表格操作列通过作用域插槽拿到行数据row弹窗通过共享form响应式对象实现了新增和编辑的复用。能把这段跑起来并看懂Vue.js 基础入门的核心骨架就算搭起来了。3.4 用 Devtools 正确调试组件树和状态面板怎么看代码写完了页面也跑出来了怎么调试才是关键。打开浏览器开发者工具你会看到多出一个 “Vue” 面板也可能叫 “Vue DevTools”。这个面板里有两个新手最常用的视口Components和Timeline。Components 视口会以树状结构展示当前页面所有组件上面那套UserManage里的ElTable、ElDialog都能一层层展开。选中某个组件右侧能看到它的 props、data 和 computed。这个功能几乎等于给项目做了一次实时“体检”当页面数据不对时先来这里看组件的 state 到底是啥比在模板里到处 console.log 高效得多。Timeline 视口会展示 Vue 内部的各种事件比如组件挂载、路由切换、Pinia 状态变化排查“某个状态到底是什么时候被改掉的”这类问题非常好用。调试事件溯源时我通常会做三步先在 Components 里看当前值再在代码里跑一次操作再切回 Timeline 看变更轨迹。有了这套流程新手遇到的绝大多数“页面不更新”的奇怪问题都能自己查出来。4. 常见问题排查实录从 devtools 打不开到数据不更新4.1 硬核排查Vue.js devtools (v5) 插件为什么打不开了这个问题在热词里刷屏确实折磨了不少人。先说一个很多人不知道的事实老版本的 Vue.js devtools v5 对应的其实是 Vue 2 时代。如果你是从第三方下载站拖进来一个“v5.crx”之类的安装包安装时浏览器可能提示“无法从此网站安装”或者装完图标置灰、点开没有反映原因大概率不是程序坏了而是新旧机制不匹配。从 Chrome 88 开始浏览器对扩展的管控大幅收紧手工拖拽安装的 CRX 扩展被默认视为不可信来源重启浏览器后可能自动停用。同时新的扩展标准要求 Manifest V3老版 v5 插件基于旧标准写在新版浏览器环境里就是“带病运行”。所以排查顺序应该是打开扩展管理页地址栏输入chrome://extensionsEdge 是edge://extensions确认插件的开关是打开的重启一下浏览器看图标是否恢复检查安装来源如果显示“已停用”或“不受支持”直接移除旧版到 Chrome 官方商店 / Edge 加载项商店搜 “Vue.js devtools”安装带官方标识的新版确认项目运行环境devtools 只对开发构建的 Vue 生效如果你访问的是npm run build出来的线上文件或者 server 渲染页面Vue 在生产模式默认关闭 devtools 检测所以必须连到本地开发服务器地址比如localhost:5173检查 Vue 版本新版 devtools 对 Vue 3 的支持已经成熟如果你还在项目里用 Vue 2部分功能会显示不支持这时应该改用 Vue 2 对应的 old 分支版本检查扩展权限右键插件图标选“扩展选项”看有没有打开“允许访问文件网址”。如果你直接用 file:// 协议打开 HTML 文件调试这个权限不开的话devtools 面板是空的清缓存和浏览器数据偶发的面板空白可以先关掉开发者工具清掉localhost的站点数据再刷新还有一个容易被忽略的坑浏览器里可能装了多个同名扩展。比如旧版 v5 没删干净又装了新版两者冲突导致图标不亮。解决方案很粗暴把所有 Vue 相关的扩展全部移除只保留最新版一个重启浏览器。我把这套排查流程整理成速查表调试时照着走现象优先排查解决动作图标灰色点击无反应扩展未启用或来源不可信重新安装官方商店版本面板打开但显示 “No Vue apps detected”页面不是 Vue 开发环境访问 dev server确认路由正确Vue 2 项目用了新版 devtoolsVue 版本与面板不匹配换用支持 Vue 2 的版本本地打开 HTML 文件没有面板缺少文件访问权限扩展选项中开启“允许访问文件网址”扩展本身正常但经常闪断多个扩展版本冲突清掉旧版只保留一个4.2 高频报错改了数据页面不动、v-for 警告、跨域请求失败改数据页面不更新这个问题的根源九成在响应式丢失。最常见的情况是你把一个不具备响应性的普通对象赋给了响应式变量或者直接给响应式对象添加了新的reactive外层结构。比如在script setup里这样写const obj reactive({ list: [] }) // 某个接口回调里直接整体替换了 obj.list obj.list plainArrayFromFetch如果plainArrayFromFetch是普通数组赋值后整个obj.list的响应式代理被替换成了普通数组再改它页面就不动了。正确做法是先确保数据是响应式的再考虑赋值时机const list ref([]) // 接口回调里list.value plainArrayFromFetch看到没有用ref包一层赋值时.value始终是响应式的容器怎么换内容都不丢响应性。这也是我推荐新手多用ref的原因。v-for 每次刷新都报警告最常见是漏了key或者 key 用了重复值。当列表项是纯展示型数据时用下标 index 可以但只要有输入框、选中状态、自定义组件就必须用唯一 id否则 Vue 复用不了组件内部的局部状态会出现输入框内容串行的诡异现象。跨域请求失败是接后端接口时的经典问题。浏览器安全策略禁止从localhost:5173直接请求http://api.example.com解决方式在 Vite 里配置代理而不是后端开 CORS 允许所有来源。做法是在vite.config.js里加server: { proxy: { /api: { target: http://api.example.com, changeOrigin: true, rewrite: path path.replace(/^\/api/, ) } } }改完配置文件记得重启npm run dev否则不会生效。这一步特别容易忽略改了代理文件却忘了重启来回折腾十几分钟才发现是服务器没刷新。4.3 给新手的三个避坑建议第一不要背 API。Vue 的 API 实在太多背了不用一周就忘。我的经验是把项目里常用的几十个 API 用熟了其余靠官方文档查阅。学会查文档的能力比记忆力重要得多官方文档有搜索功能查一次比背诵半小时有效。第二早期别碰自定义指令和复杂混入。新手阶段搞不清这些抽象层级容易写出自己都看不懂的代码。先把组件化、路由、状态管理这三板斧练扎实再考虑去理解更灵活的底层抽象。第三多看 Vue Devtools少写 console.log。调试能力是工程能力的隐形分水岭。每次“页面为什么不渲染”的疑惑先去 Devtools 看组件状态和数据流你会慢慢建立起“数据到底是哪里出错”的直觉这个直觉会让后续学习和工作快很多。最后再分享一个小技巧我实测下来给刚接触 Vue.js 的朋友最快的成长路径是找个简单页面比如商品管理、用户管理用 Element Plus 从头抄一遍、跑通、再改一点自己的需求。不要贪多求全一个页面完成增删改查后再尝试加一两个路由和 Pinia 状态管理Vue 的底层逻辑基本就通了。还有一个细节开发小白拿到项目时先看package.json里的脚本命令然后只用npm run dev这一个命令就够了其他命令暂时不碰。很多人一上来把npm run build也执行了结果产物在 dist 目录页面改半天看不到效果实际上是因为构建产物不会热更新。说白了Vue.js 入门没那么玄乎本质就是“数据驱动视图 组件拼接 工具链辅助”三件事。把我在前面写的那些核心概念吃透再亲手跑通一个带 Element Plus 的增删改查页面你就已经能应对不少日常开发场景了。剩下那些更高级的主题等遇到真实需求时再回头查水到渠成。
返回列表