
拿到这个作业题目的时候我先愣了一下——“wed前段第一次作业”大概率是“web前端第一次作业”的笔误。不过没关系这个标题背后对应的场景我太熟了一个刚接触前端不久的新人拿到老师或者课程布置的第一次网页开发作业脑子里一团乱麻不知道从哪里下手也不知道做到什么程度算“能交差”。这篇文章就是写给你的。我会用一篇完整的前端新手作业指南把“第一次做web前端作业”这件事拆开揉碎讲清楚从拿到题目怎么拆解需求到写页面时那些防不胜防的坑再到最后部署上线、准备验收答辩。全程不会像教科书那样端着也不会甩一堆你暂时用不上的概念就按真实做项目的思路往下捋。1. 内容整体设计与思路拆解1.1 先搞明白第一次作业到底在考察什么很多新手拿到作业题目就急着打开编辑器敲代码这个习惯很不好。第一次前端作业的核心目的不是让你做一个多惊艳的网站而是考察你有没有建立起“工程化思维”的雏形。什么叫工程化思维往小了说是文件夹分门别类、HTML/CSS/JS 各司其职往大了说是懂得先规划再做、遇到问题知道去哪找答案、做完之后会自查和总结。这些习惯比任何炫技的动画效果都值钱因为它们直接决定你三年后是变成“只会贴代码的切图仔”还是能独当一面的前端工程师。从热词里能看到一个高频词前端面试题。你在简历上写“独立完成过xx项目”面试官一定会追问“你当时怎么设计页面结构的”“遇到跨域怎么处理的”“首屏加载怎么优化的”。第一次作业就是你面试素材的起点哪怕它再简单只要你把“为什么这么写”想清楚了它就能成为你面试时拿得出手的项目经历。1.2 选题与范围控制别一上来就憋大招如果作业是自拟题目我强烈建议你做一个“小而完整”的东西而不是一个“大而残缺”的东西。比如“个人介绍页面作品展示列表留言板”听起来朴素但它完整覆盖了前端三板斧静态页面展示能力HTML/CSS、简单的交互逻辑JS表单校验、点击切换、数据理解数组渲染、数据存储。反过来如果你选“仿淘宝商城”页面还没写三分之一就到截止日期了最后只能交一个半成品反而暴露短板。我第一次带新人时见过一个学员作业选了“在线音乐播放器”结果两周时间光研究 audio API 就花了一周最后整个页面只有播放按钮是能用的。这就是典型的范围失控。记住好的作业不是功能多而是每个功能都经得起追问。1.3 技术栈选型什么时候该用原生三件套什么时候该上框架第一次做前端作业我建议优先选择原生 HTML CSS JavaScript而不是直接上 Vue 或 React 框架。原因很简单框架会替你封装掉太多底层细节。比如你用 Vue 写一个列表渲染v-for 一行搞定但如果你不理解背后的 DOM 操作逻辑后面学 diff 算法、响应式原理时就是空中楼阁。热词里那些 “vue3element plus 前端项目自适应大屏方案”“vben前端框架”“qiankun微前端” 都是后话它们建立在你对原生 JS 有扎实理解的基础上。当然如果作业明确要求用框架那就另说。但哪怕用框架我也建议你先用原生写一遍核心页面的静态版本搞清楚每个 UI 区块怎么布局、样式怎么组织再迁移到框架里。这能帮你省掉大量“为什么组件样式不生效”的排查时间。2. 核心细节解析与实操要点2.1 目录结构一出手就要有工程感你在 GitHub 上看开源项目时会发现一个好的项目目录是有规律的。第一次作业不需要弄得多复杂但至少要分门别类project-root/ index.html // 首页 pages/ // 其他页面放这里 about.html gallery.html css/ style.css // 全局样式 pages/ // 各页面独有样式可选 js/ main.js // 全局脚本 pages/ // 各页面独有脚本可选 assets/ images/ fonts/ README.md // 项目说明这个很加分这个结构的好处是你写第二个页面时不需要把第一个页面的样式再看一遍才能找到改哪里你交作业时老师一眼就能看出你有模块化意识。很多新手喜欢把所有东西堆在根目录下叫index1.html、index2.html、final版本.html这种命名方式在你以后做真项目时会被同事疯狂吐槽趁早改掉。还有一个细节我放在前面说HTML 文件的命名不要用中文不要有空格全部小写用-连接。my first page.html在本地双击打开没问题一旦部署到服务器URL 编码问题会让你排查到怀疑人生。2.2 HTML 语义化别全程 div第一次作业最常见的问题就是满屏div。不是说不能用 div而是你要知道HTML5 提供了headernavmainsectionarticleasidefooter这些语义化标签它们能让你的页面结构“会说话”。举个例子页面的导航区域用nav包裹接屏幕阅读器的用户能直接跳过导航进入正文搜索引擎的爬虫也能更准确地识别你的页面结构。我面试的时候会刻意看候选人的页面语义化水平因为这体现了一个人是否真的理解页面是“给人看的”而不仅仅是“让浏览器渲染的”。写 HTML 时还有几个小细节图片标签必须有alt属性哪怕是个空字符串。这是无障碍的基本要求也会在浏览器加载图片失败时显示友好的替代文本。表单控件的label一定要用for属性关联对应控件的id。新手很容易忽略但这是可访问性踩分点。lang属性要设置正确中文页面写html langzh-CN这会影响浏览器翻译插件和语音朗读的行为。2.3 CSS 布局的三大流派与取舍布局是第一次作业中最耗时、最容易受挫的部分。你现在能搜到的布局方案基本就三种传统盒模型 display布局、flex布局、grid布局。我推荐你以 flex 为主、grid 为辅来组合使用。flex适合处理一维布局比如水平导航栏、卡片列表、垂直居中代码量少逻辑好理解。它的核心就是两条轴主轴和交叉轴justify-content管主轴方向的对齐align-items管交叉轴方向的对齐。你只要把这两者搞明白页面上 80% 的布局问题都能解决。grid适合处理二维布局比如图片展览区、商品列表、整个页面的整体骨架。它把页面划分成行和列元素可以精确地放到网格的任意区域。举个我可以直接抄作业的思路.gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 16px; }这五行代码就能实现一个自适应的图片画廊窗口变窄时列数自动减少图片不会被挤压变形。这个技巧放在第一次作业的“作品展示”区域视觉效果直接拉满。还有一个必须养成的习惯所有图片都要设置max-width: 100%。不设这条图片超出容器宽度时就会横向撑破布局这是新手页面最常见的“破相”原因。2.4 CSS 命名与样式组织第一次作业的 CSS 文件很容易变成一团乱麻最后写出来的样式自己都不敢改。解决这个问题的一个低门槛方法按模块写注释分节。/* 全局基础样式 */ body { ... } a { ... } /* 导航栏 */ .navbar { ... } .navbar__link { ... } /* 作品卡片 */ .card { ... } .card--featured { ... }你能看到我用到了 BEM 命名法的部分思想.block__element--modifier。.navbar__link表示导航栏的子元素链接.card--featured表示卡片的“精选”变体。新手不要求完全掌握 BEM但一定要理解一个原则类名要表达“这个元素是什么”而不是“这个元素长什么样”。我以前见过有人写.red-big-text后来需求一改文字要变蓝色变小了类名就显得很滑稽。样式会变语义不会变命名要冲着语义去。2.5 JavaScript 部分初级作业最合适的交互方向第一次作业的 JS 不需要写多难。我推荐的交互清单是表单校验比如留言板提交前检查姓名是否为空、邮箱格式是否正确。Tab 切换把“个人介绍/作品集/联系方式”做成三个标签页。返回顶部按钮页面滚动超过一定距离时出现点击回到顶部。导航高亮滚动时根据当前区块切换导航菜单的高亮状态。如果要用真实的数据展示可以练习fetch请求一个公共 API比如天气接口、必应壁纸接口并把数据渲染到页面上。这里会踩到一个很经典的前端问题跨域CORS。我简单解释一下跨域浏览器出于安全考虑规定一个页面只能请求与它同源同协议、同域名、同端口的接口。你本地打开file://协议的文件去请求别人https://接口大概率会被拦截。解决跨域的常用方案有三种用jsonp只支持 GET老技术了、让后端配cors响应头需要服务端配合、本地开发时用代理需要构建工具。新手第一次作业如果遇到跨域最实用的建议是直接用命令行起一个本地静态服务# 如果安装了 Python 3 python -m http.server 8080 # 如果你在用 VS Code装 Live Server 插件右键 - Open with Live Server这样你的页面就跑在http://localhost:8080下协议和域名是固定的很多奇怪的本地问题就不存在了。3. 实操过程与核心环节实现3.1 从零到一页面骨架搭建的现场示范我们以“个人工坊展示页”为例子模拟一个完整的实操流程。第一步确定页面结构。我习惯先在纸上或者思维导图里画出区块划分顶部固定导航包含姓名/Logo、三个菜单项。Hero 区一句有冲击力的自我介绍 一个按钮点击弹出个人简历弹窗。作品区网格布局展示3~4个虚拟项目的卡片鼠标悬停有交互效果。关于区一段个人介绍 技能标签列表。留言区一个简易留言表单前端校验后把留言渲染到下方列表。底部联系方式链接。这六个区块能覆盖语义化标签、flex/grid布局、JS交互、表单操作作为一个第一次作业已经相当完整。3.2 手写核心代码HTML 骨架!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 titleXX的个人工坊 - 首页/title link relstylesheet hrefcss/style.css /head body header classnavbar div classnavbar__logoXX的工坊/div nav classnavbar__menu a href#works classnavbar__link作品/a a href#about classnavbar__link关于/a a href#contact classnavbar__link留言/a /nav /header main section classhero h1你好我是XX/h1 p一个正在学习前端开发的人热爱把想法变成页面。/p button idintroBtn classhero__btn点击认识我/button /section section idworks classworks h2我的作品/h2 div classworks__grid !-- 作品卡片由 JS 动态生成 -- /div /section section idabout classabout h2关于我/h2 p……/p ul classabout__skills liHTML/li liCSS/li liJavaScript/li /ul /section section idcontact classcontact h2给我留言/h2 form idmsgForm classcontact__form label forname昵称/label input typetext idname namename required label formessage留言内容/label textarea idmessage namemessage rows4 required/textarea button typesubmit提交留言/button /form ul idmsgList classcontact__messages/ul /section /main footer classfooter p© 2025 XX的工坊 | 用 ❤️ 和键盘制作/p /footer script srcjs/main.js/script /body /html注意我在表单里用了required属性。这是 HTML5 自带的前端校验点击提交时如果为空浏览器会直接拦截并提示不需要你写 JS 判断。第一次作业能用原生能力解决的就别手写重复代码这也是“工程效率”意识的一部分。3.3 核心样式flex 布局与 grid 布局实战/* 全局基础 */ * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: system-ui, -apple-system, Segoe UI, PingFang SC, Microsoft YaHei, sans-serif; line-height: 1.6; color: #1f2933; background-color: #f9fafb; } /* 导航 */ .navbar { position: sticky; top: 0; display: flex; justify-content: space-between; align-items: center; padding: 12px 32px; background-color: #ffffff; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06); z-index: 10; } .navbar__menu { display: flex; gap: 24px; list-style: none; } .navbar__link { text-decoration: none; color: #3e4c59; font-weight: 500; transition: color 0.2s ease; } .navbar__link:hover { color: #2563eb; } /* Hero */ .hero { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 80px 24px; text-align: center; background: linear-gradient(135deg, #eff6ff, #e0e7ff); } .hero h1 { font-size: 48px; margin-bottom: 12px; } .hero__btn { margin-top: 24px; padding: 10px 28px; border: none; border-radius: 999px; background-color: #2563eb; color: #ffffff; font-size: 16px; cursor: pointer; transition: transform 0.2s ease, background-color 0.2s ease; } .hero__btn:hover { background-color: #1d4ed8; transform: translateY(-2px); } /* 作品网格 */ .works__grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 24px; padding: 24px 0; } .card { background: #ffffff; border-radius: 12px; overflow: hidden; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.06); transition: transform 0.25s ease, box-shadow 0.25s ease; } .card:hover { transform: translateY(-6px); box-shadow: 0 8px 24px rgba(37, 99, 235, 0.12); } /* 留言列表样式 */ .contact__messages li { background: #ffffff; padding: 12px 16px; border-radius: 8px; margin-bottom: 8px; border-left: 3px solid #2563eb; }这里有几个细节值得说。box-sizing: border-box是救命的如果不设它padding 会撑大元素实际占位新手布局错乱十有八九是栽在它身上。position: sticky可以让导航栏滚动时吸附在顶部这个属性兼容性已经非常好了比fixed更好用因为它不会脱离文档流。按钮的transform: translateY(-2px)配合transition能做出很自然的上浮悬停效果不需要写动画库。3.4 JavaScript 交互从 DOM 到数据渲染// 弹窗按钮 const introBtn document.getElementById(introBtn); if (introBtn) { introBtn.addEventListener(click, () { alert(嘿欢迎来到我的工坊这是你的第一次访问吗); }); } // 动态渲染作品卡片 const worksData [ { title: 个人博客, desc: 用 HTML/CSS 构建的静态博客页面, tag: 页面设计 }, { title: 待办清单, desc: 支持添加、完成、删除的待办应用, tag: JS交互 }, { title: 照片画廊, desc: 使用 Grid 构建的响应式画廊, tag: 布局练习 }, { title: 天气查询, desc: 调用公共 API 展示天气数据, tag: 数据请求 } ]; const grid document.querySelector(.works__grid); if (grid) { worksData.forEach((item) { const card document.createElement(article); card.className card; card.innerHTML div styleheight: 140px; background: linear-gradient(135deg, #bfdbfe, #c7d2fe);/div div stylepadding: 16px; h3${item.title}/h3 p${item.desc}/p span classcard__tag${item.tag}/span /div ; grid.appendChild(card); }); } // 留言板提交并渲染 const msgForm document.getElementById(msgForm); const msgList document.getElementById(msgList); function renderMessages() { const messages JSON.parse(localStorage.getItem(messages) || []); msgList.innerHTML ; messages.forEach((msg) { const li document.createElement(li); li.textContent ${msg.name}: ${msg.text}; msgList.appendChild(li); }); } if (msgForm) { msgForm.addEventListener(submit, (e) { e.preventDefault(); const name document.getElementById(name).value.trim(); const text document.getElementById(message).value.trim(); if (!name || !text) { alert(请填写昵称和留言内容); return; } const messages JSON.parse(localStorage.getItem(messages) || []); messages.push({ name, text }); localStorage.setItem(messages, JSON.stringify(messages)); msgForm.reset(); renderMessages(); }); } // 页面加载时渲染已有留言 renderMessages();这里有三个特别想让新手记住的做法第一个是createElement动态创建 DOM 节点。很多新手会直接拼字符串innerHTML但把用户输入的内容直接塞进innerHTML是非常危险的做法会造成XSS跨站脚本攻击风险。用户在留言框里输入一段img srcx onerroralert(1)这种代码如果用innerHTML插入脚本会在别人浏览你的页面时执行。用textContent就安全很多它会原样显示用户输入的文字不会解释成 HTML。这是 web 安全里最基本的一课。第二个是localStorage。你刷新页面留言不会丢因为数据存到了浏览器本地。这比把留言存在 JS 变量里强太多了。为什么用这个因为第一次作业没有后端localStorage是实现“数据持久化”最轻量的方案。当然它也有局限数据只对当前浏览器生效换台电脑就没了但作业阶段够用了。第三个是e.preventDefault()。表单提交的默认行为会刷新页面你必须取消它才能在页面不跳转的情况下执行你自己的 JS 逻辑。每次写表单提交第一行就写它养成本能反应。3.5 响应式适配一个容易拿加分项的好习惯第一次作业你只需要掌握一个基础的响应式手段媒体查询。media (max-width: 600px) { .navbar { flex-direction: column; gap: 8px; padding: 16px; } .hero h1 { font-size: 30px; } .works__grid { grid-template-columns: 1fr; } }这段代码的意思当视口宽度小于等于 600px 时导航栏垂直排列作品网格变成单列。你不需要实现多复杂的适配只要保证手机上的布局不乱、字能看清、按钮能点就已经超过了班里一大半同学。顺带一提大屏适配在项目里往往比小屏更难。前端热词里能看到“vue3element plus 前端项目自适应大屏方案”那是一套在大屏监控场景下让px自动换算成视口单位的方案通常用rem 动态设置根字体大小或者transform: scale()整体缩放。第一次作业暂时不用碰这个但心里要有个印象以后做可视化大屏项目时会用到。3.6 动效与细节打磨写完功能之后花一个小时打磨细节性价比极高。我给你几个低成本的细节优化方向滚动平滑html { scroll-behavior: smooth; }一行代码让锚点跳转不再生硬。导航高亮用IntersectionObserver监听各区块进入视口给对应的导航链接加高亮类。这个 API 比监听scroll事件性能更好。按钮反馈所有可点击元素设置cursor: pointer按钮默认不是手型并加:active状态按下去时有颜色变化。图片懒加载img loadinglazy页面滚动到图片位置时才加载对大图多的页面性能提升明显。这些细节在你的作业演示时会成为肉眼可见的加分点老师会感受到“这个学生不只完成了功能还考虑了用户体验”。4. 常见问题与排查技巧实录4.1 图片下方多出一截空白去不掉几乎每个新手都遇到过。解决方案给图片设置display: block或者给容器设置font-size: 0。原因是图片默认inline属性基线对齐时会在底部留下空隙。这是 CSS 基本功里的经典问题面试也爱问。4.2 CSS 样式写了但不生效先别急着换选择器按顺序排查是否引入了 CSS 文件检查link标签的href路径路径是相对哪个文件的位置这个最容易错。选择器的优先级是不是被覆盖了写内联样式style必定优先于外链样式.class优先于tag。浏览器缓存按CtrlShiftR强制刷新清掉缓存再看。语法错误打开开发者工具的 Console 面板如果有红色报错多半是前面某个大括号没闭合。4.3 打开开发者工具Console 报 “Failed to load resource: net::ERR_FILE_NOT_FOUND”大概率是script或link标签的路径写错了。注意相对路径是相对于当前 HTML 文件的位置。假设你在pages/about.html里引用../js/common.js那就表示去上一级目录找js文件夹。开发时我强烈建议用 VS Code 的 Live Server它不仅能解决部分路径问题还支持热更新。4.4 热搜词“加载 web 视图时出错: error: could not register service worker: invalidstatee”怎么理解这个报错来自 PWA渐进式 Web 应用项目Chrome 浏览器在注册 Service Worker 时状态无效。新手第一次作业基本不会碰上但如果你试过用 Vite PWA 插件或自己手动注册 SW就可能遇到。一个常见原因是你的页面不是通过 HTTPS 或localhost提供Service Worker 只有在安全上下文才能注册。解决办法是确保在http://localhost或 HTTPS 环境下开发。其实 Service Worker 的知识对你之后做离线缓存、消息推送很有用但现在可以先放着。我第一次了解它也是因为踩了同样的报错后来花了很长时间才真正搞懂它的生命周期。4.5 部署到 nginx 后刷新子页面 404如果你作业用的是“多页布局”比如pages/about.html直接在浏览器访问没问题但部署到服务器后用 nginx 配置了try_files不合理就会出问题。看清这个场景nginx 服务器上如果要部署多个 web 项目处理一个路径不存在的页面时可能导致子页面路由刷新后返回 404。正确的 nginx 站点配置大致形式是server { listen 80; server_name your-domain.com; root /var/www/project-a; # 项目A目录 index index.html; location / { try_files $uri $uri/ 404; } }这里的try_files意思是先找真实文件找不到就尝试目录再找不到就返回 404。如果做的是单页应用SPA并依赖 history 路由模式这里还要多一个把请求回退到index.html的配置不过第一次作业涉及不到留个印象即可。4.6 表单提交后页面总刷新JS 没执行忘了e.preventDefault()。表单的默认提交事件在 JS 监听器执行结束后照样会触发表单提交刷新页面你的 JS 数据就全没了。我见过不下十个新人在这个地方急得团团转。4.7 布局在电脑上好好的手机上一看就崩要么是没写meta nameviewport contentwidthdevice-width, initial-scale1.0要么是用了固定宽度比如width: 1200px。改成自适应宽度块级元素默认占满父容器配合max-width限制最大宽度padding控制内边距才是正确姿势。5. 部署上线与验收答辩准备5.1 首次部署零成本把作业放上公网作业做完部署上线这一步一定要做。你可以在简历上写“项目已上线可在线访问”这和“本地可运行”完全是两个级别的说服力。新手推荐两条路第一条是GitHub Pages。在 GitHub 上新建仓库把项目推到main分支再到仓库的 Settings - Pages 里选择分支等一两分钟就能访问https://你的用户名.github.io/仓库名/。注意GitHub Pages 托管的是纯静态文件PHP、Java、Node 后端都用不了但纯前端作业完全够。它的优点是免费、稳定、全球访问。第二条是本地 nginx 部署更适合你以后在公司里用。把前端构建产物放到 nginx 的html目录或自定义站点目录改一下配置文件重启服务就能通过本机 IP 在局域网内访问。对第一次作业来说你在自己电脑上装个 nginx再把项目拷进去浏览器访问http://localhost就能看到效果这也是一种“上线”。推荐你两个都试一遍GitHub Pages 用于交作业链接nginx 帮你提前了解服务器的概念。注意所有涉及公网演示的场景里不要在页面留下任何真实账号、密码、密钥之类的敏感信息。5.2 验收答辩老师或面试官会问什么如果你的作业需要答辩提前准备几个问题的答案会显得非常从容你这个项目的目录结构为什么这么设计这个卡片布局是用什么方式实现的为什么选 grid 而不是 flex留言板的留言存在哪里为什么不会在刷新后消失你遇到过最棘手的问题是什么怎么解决的如果给你一周时间继续优化你会做什么前四个问题你要是认真按这篇文章的思路走完都能回答上来。第五个问题的答案建议这样准备把静态页面迁移到 Vue3 框架、接入真实后端实现留言的持久化存储、增加用户登录功能、做 PWA 离线访问。这些方向能体现你对未来学习的规划。5.3 作业总结的写法最后一步写一份 README 或作业说明不要小看它。内容建议包含项目简介这个项目是什么解决什么问题。技术栈用了哪些技术为什么这么选。目录结构说明。如何本地运行命令或步骤写清楚。项目亮点列出你认为做得最好的两个点附上理由。遇到的难点及解决过程。后续计划。这份文档的质量某种意义上比代码本身更能体现你的沟通能力和总结能力。以前我带过一个新人能力不算突出但每份文档都写得特别清楚快速得到了团队信任。这个习惯从第一次作业就可以开始养成。6. 做完第一次作业之后下一步往哪走6.1 热词里的“前端学习路线”“前端开发者学习后端Java知识计划”怎么理解做完第一次作业你已经体验了“页面搭建 交互逻辑 数据存取”的完整链路。接下来有两个方向一个是继续向前端深处走深入学习 JavaScript 核心作用域、闭包、原型链、异步、组件化开发、打包工具Vite/Webpack、框架Vue/React、工程化ESLint、Git 规范、CI/CD。热词里的“qiankun微前端入门”就是一个高级话题它是让多个独立前端应用组合成一个大厅的架构方案你至少得先把一个应用做好做透再考虑微前端。另一个是向后端延伸前端工程师懂后端很有优势。热词里有一条很真实“前端开发者学习后端Java知识计划”。我的建议是先学好 HTTP 协议和 RESTful API 设计动手用 Node.js 的 Express 或 Python 的 Flask/FastAPI 写一个简单的接口再考虑要不要深入 Java。千万不要一上来就啃 Spring 全家桶你会被配置和依赖整崩溃。Python 的 web 框架如果用得顺手dash 也可以用来做纯 Python 的数据可视化页面但它不适合做常规的业务网站。6.2 从作业到简历作品意识比作业本身更重要第一次作业最大的意义不是得高分而是让你建立“作品思维”。什么叫作品思维就是凡事做出一个别人能打开看、能交互、能稳定运行的东西并且把创作过程记录下来。这样一年后你会有好几个作品而不是一堆“练习”。以后你学到一个新技术比如 WebSocket、Canvas、WebRTC就把它加到一个能跑的页面里放到 GitHub 上文档写好。当你开始找实习、找工作的时候这些作品就是你有力的证明。我见过太多候选人简历上写着“熟悉 Vue3”但问他做过什么只能说出“看过视频、写过 demo”。那种“看过”和“做成作品”之间的差距会随着年龄增长越来越明显。6.3 最后再说两句新手安身立命的建议每次做项目给自己规定一个“完成时间”而不是“无限打磨时间”。第一次作业不要追求完美主义规定三天完成基本功能第四天打磨细节第五天部署总结。超时就砍功能保证交付。写代码遇到问题优先自己调试、查文档、搜报错信息。把问题描述清楚去问别人也是一种能力但前提是你已经尝试过。热词里的“CTF web解题 找flag夺旗赛”本质上就是一个个具体漏洞场景的排查训练和调试前端页面在思路上是相通的从一个现象出发找到藏在里面的关键信息然后一步步接近目标。做前端这行最珍贵的品质是“手痒”和“好奇”。看到一个网页布局好看会想打开控制台看看它怎么实现的看到一个接口返回数据会想试试点开网络面板看看请求头。保持这种状态第一次作业远不是终点它更像是一扇门推开之后你会发现前端这个领域大到足够你折腾很多年而且每进入一层都会有新的乐趣。我自己做过太多从零到一的项目最大的体会是不要怕项目小面子里子都靠积累。第一次作业是你积累的起点愿你从此一路写下去写出一个属于自己的、不断成长的数字作品集。