ARTICLE DETAIL

资讯详情

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

不用后端的个人博客:纯HTML+CSS+JS源码搭建与部署指南

不用后端的个人博客:纯HTML+CSS+JS源码搭建与部署指南 简介一套面向个人博客场景的 HTMLCSS 静态网页源码适合想搭建个人展示页、记录日常或学习前端基础的博主与初学者无需后端数据库上传到静态托管服务即可访问。页面由 index.html 定义结构化骨架head、header、nav、article、footer 等标签分别承担标题信息、页头、导航、文章区和页脚style.css 统一负责字体、颜色、间距与整体布局盒模型、浮动、定位等经典 CSS 技巧都在其中有所体现ID 与类选择器的配合也便于理解样式组织。压缩包共 30 个文件除 HTML 和 CSS 各 1 个外还包含 27 个 GIF 装饰图与 1 张 JPG 照片整体仅 37KBGIF 素材多用作分隔线、按钮背景和页脚装饰替换方便整体结构清晰适合零基础快速套用。已有 3814 人学习下载使用者既可以对照源码拆解博客页面结构与样式写法也可以直接换掉图片和文字生成自己的个人博客页面对入门者很有参考价值。1. 一个不用后端就能跑的个人博客HTML静态源码到底能干什么做技术的人想搞个人博客第一反应往往是去装 WordPress、配数据库、买服务器结果折腾一晚上文章还没写环境先崩了。这套“个人博客网页设计 html 源码”要解决的正是这个场景它是一份纯静态的博客前端工程不需要 PHP、不需要 MySQL本地双击 index.html 就能预览扔到任意支持静态页面的托管平台上就能上线。别人访问到的页面效果和你本地看到的基本一致。它适合三类人第一类是前端刚起步、想找一份完整代码拆着学的第二类是只想有个干净博客写技术笔记、不打算碰服务器运维的第三类是拿它当课程设计或毕设演示的改改配色、换换文章卡片就交差。这套源码的内核很简单——HTML 负责语义结构CSS 负责布局和响应式JS 负责滚动、返回顶部这类交互。理解这三层怎么协作比拿到源码本身更有价值。今天这篇就把这套模板拆开从选型逻辑讲到怎么改、怎么部署、踩过哪些坑。2. 静态博客技术选型HTMLCSSJS 三层到底怎么分工这一章先把“为什么纯 HTML 源码能撑起一个博客”讲透再分别拆解 HTML、CSS、JS 的具体角色。只有明白三层各自的边界你后面改代码才不会改出“样式没生效”“文章点不进去”这类问题。2.1 为什么用静态博客而不是 WordPress先算一笔账。WordPress 跑起来需要 Web 服务器、PHP 解释器、MySQL 数据库最低配云服务器一年几百到几千加上域名备案学习成本至少一周而静态博客只需要一堆 .html、.css、.js 文件托管到 GitHub Pages、Gitee Pages 或对象存储上走 HTTP 就能访问成本为零。静态方案在写技术博客时有个非常实际的好处文章就是纯 HTML 片段加载路径短没有数据库查询首屏渲染快。内容安全可控不会被插件漏洞拖累备份就是把整个目录打压缩包。缺点是动态能力弱——没有评论、没有站内搜索、没有后台编辑器。对应方案也成熟评论用第三方脚本接入搜索交给第三方搜索框写作直接在本地编辑器里改 HTML 或 Markdown。这套源码的定位就是静态方案的成品模板省掉你自己从零搭建布局和样式的功夫。你拿到手做的第一件事应该是摸清楚文件结构而不是急着改样式。2.2 HTML5 语义化标签搜索引擎和浏览器都爱读的结构打开源码里的 index.html会发现它没用一堆无意义的 div 层层嵌套而是用了完整的 HTML5 语义标签。大概结构是这样!DOCTYPE html html langzh-cn head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 meta namedescription content个人博客记录技术与生活 title我的个人博客/title link relstylesheet hrefcss/style.css /head body header classsite-header h1我的个人博客/h1 nav classmain-nav ul lia hrefindex.html首页/a/li lia hrefarchive.html归档/a/li lia hrefabout.html关于/a/li /ul /nav /header main classcontent-wrap article classpost-card h2a hrefposts/first-post.html第一篇博客/a/h2 p classpost-meta2024-12-01 · 前端/p p这里是文章摘要通常保留一到两句话。/p a classread-more hrefposts/first-post.html阅读全文/a /article /main footer classsite-footer p© 2024 我的个人博客/p /footer script srcjs/main.js/script /body /html这串代码里header告诉浏览器这里是站点头部nav是导航区main是主体内容article是一篇完整的文章卡片footer是页脚。搜索引擎爬虫对语义化标签的权重理解远高于 class 命名这是 SEO 的地基。meta nameviewport这行值得单独讲没有它手机浏览器会按桌面宽度渲染再缩小页面字体小到需要双指放大。langzh-cn声明页面语言影响浏览器翻译插件和屏幕阅读器的判断。引入 CSS 用link引入 JS 用script两个标签都放在合理位置——CSS 在head里提前加载JS 在body末尾避免阻塞渲染这两条是页面性能的常识。提示改模板时保持langzh-cn不要动删掉它会让中文页面在部分浏览器里被误判成其他语言连带着翻译插件也会乱来。2.3 CSS 这一层布局、响应式与设计变量CSS 在这套源码里承担三件事视觉风格、栅格布局、响应式适配。样式文件一般拆成基础重置、布局、组件、响应式四个区块方便定位。:root { --bg-primary: #f5f5f5; --bg-card: #ffffff; --text-primary: #333333; --accent-color: #2d6cdf; --max-width: 760px; } * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: -apple-system, BlinkMacSystemFont, Segoe UI, PingFang SC, Microsoft YaHei, sans-serif; background-color: var(--bg-primary); color: var(--text-primary); line-height: 1.8; } .post-card { background: var(--bg-card); max-width: var(--max-width); margin: 20px auto; padding: 24px 28px; border-radius: 8px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06); }注意:root里的--bg-primary这类自定义属性这是 CSS 变量全站颜色、间距、最大宽度都统一从这几个变量取值。想换主题色找到--accent-color: #2d6cdf改成你喜欢的色值所有用到它的按钮、链接、高亮文字会同步变色不用一个一个找。响应式的关键是媒体查询。这套源码一般在文件末尾有一段针对小屏的适配规则media (max-width: 768px) { .content-wrap { padding: 0 14px; } .post-card { padding: 16px 18px; margin: 12px auto; } .main-nav ul { flex-direction: column; gap: 8px; } }代码逻辑不复杂屏幕宽度低于 768 像素时缩减页面内边距、卡片留白导航从横排变竖排。Media 查询本身是增量覆盖写在小屏规则里的属性会盖掉正常宽度下的同名属性优先级和源码顺序有关所以响应式规则建议统一放在文件最后。2.4 JavaScript 交互博客里真正“能动”的部分纯 HTML 和 CSS 做出来的页面是静态的JS 负责让博客有反馈感。这套模板里的 js/main.js 通常包含几段功能移动端菜单开关、点击回到顶部、导航栏滚动加阴影。核心逻辑可以拆成下面这样// 移动端菜单开关 const menuToggle document.querySelector(.menu-toggle); const navMenu document.querySelector(.main-nav ul); menuToggle.addEventListener(click, () { navMenu.classList.toggle(active); }); // 回到顶部按钮 const backTopBtn document.getElementById(back-top); window.addEventListener(scroll, () { if (window.scrollY 400) { backTopBtn.style.display block; } else { backTopBtn.style.display none; } }); backTopBtn.addEventListener(click, () { window.scrollTo({ top: 0, behavior: smooth }); });第一段给“菜单按钮”绑定了点击事件点击时给导航列表加一个active类CSS 里对应display: none和display: flex的切换完成展开收起。第二段监听滚动事件滚动超过 400 像素显示回到顶部按钮点击后用scrollTo配合behavior: smooth平滑滚回顶部。写原生 JS 时要养成好习惯每个querySelector拿到元素后先确认不是 null 再挂事件。如果页面某处删掉了对应元素JS 直接报错后面所有逻辑都会停摆。把addEventListener包在if判断里是最朴素的防御。注意滚动事件本身触发频率极高如果回调里有复杂的 DOM 操作或样式读写会有明显的性能损耗。实战中做节流处理——用requestAnimationFrame或setTimeout限制回调在每一帧内只执行一次。3. 把这套源码跑起来目录结构、改篇文章、调个样式这章进入实操。从解压后的目录结构讲起到本地预览、替换成你自己的文章、改颜色最后把站点推上线上平台。每一步都会解释命令在干什么参数怎么改。3.1 本地预览双击打开和本地服务器的差别拿到源码压缩包解压后第一件事是在本地确认它能跑。最常见的操作是双击 index.html浏览器会以file://协议打开。这样看静态效果完全没问题但有两个隐患浏览器对本地文件的 XHR 请求有限制有些 JS 特效和加载外部数据的功能会静默失败地址栏里的路径是本地磁盘路径和线上 URL 不同涉及根路径引用时容易踩坑。推荐的做法是在源码目录下起一个本地 HTTP 服务。如果你装了 Python一行命令就能搞定# 在源码根目录执行 cd your-blog-source python3 -m http.server 8080命令执行后打开浏览器访问http://localhost:8080就能看到和线上几乎一致的效果。8080是端口号如果被占用换成 8081、8090 都可以。python3 -m http.server会把你当前所在的目录作为站点根目录提供服务好处是 JS、CSS、图片资源都按相对路径正常加载和线上行为一致。没有 Python 也没关系前端开发常用的 Node.js 同样轻量npx serve -l 8080 .这句命令从 npm 临时拉取 serve 包并启动.代表当前目录作为站点根目录。临时启动不会污染全局环境适合只是简单预览的场景。3.2 从源码到一篇能看的新文章DOM 结构拆解预览没问题后先别急着改样式第一件事应该是替换成自己的内容。找 index.html 里的文章卡片部分它通常是这类结构article classpost-card div classpost-cover img srcimages/cover-1.jpg alt封面图 /div div classpost-body span classpost-category技术笔记/span h2 classpost-title a hrefposts/nginx-config.htmlNginx 配置踩坑记录/a /h2 p classpost-excerpt 这篇文章记录了我在给博客配置 Nginx 时遇到的几个典型问题包括路径匹配优先级、缓存策略和 404 排查思路。 /p div classpost-meta span classpost-date2024-11-20/span span classpost-authorEvan/span /div /div /article把标题、日期、摘要换成你自己的内容把href指向你新建的文章页面首页这一个卡片就算改完了。新建单篇文章有一个约定文件命名里不要带空格和中文一律用小写字母加连字符比如nginx-config.html。原因是线上服务器对带空格和中文字符的 URL 要做编码手一抖编码格式混了就 404。粘贴文章内容时保持标题层级清晰单篇文章页面里只有一个h1主标题下面按h2 - h3往下排。文件内的图片路径建议用相对路径比如../images/pic-1.jpg这样整个博客目录拷到任何地方路径都不会断掉。3.3 换配色和字体CSS 变量让整站只改两行模板默认的配色不一定是你要的。这套源码如果用了 CSS 变量换主题色就是改几个变量的事。日志文件大概长这样:root { --accent-color: #2d6cdf; --text-primary: #333333; --text-secondary: #888888; --bg-card: #ffffff; }把--accent-color换成#e65c41之类暖色全站按钮、链接、标签底色同步更新。--text-primary是正文主色控制文章可读性不建议调太浅——很多看博客的人是在晚上灰色文字在暗背景下直接看不清。字体方面正文通过 font-family 的候选列表实现不同系统下的最优显示body { font-family: -apple-system, BlinkMacSystemFont, PingFang SC, Microsoft YaHei, Noto Sans SC, sans-serif; }这个列表是逐个尝试苹果设备命中-apple-systemWindows 命中Microsoft YaHeiLinux 命中Noto Sans SC最后兜底无衬线体。想引入思源宋体这类外部字体需要额外引入字体文件改动量和收益看个人喜好先用系统字体栈不会出错。3.4 把博客推到线上三种免费托管方式对比本地改完最终要上线。静态博客托管有三种主流选择参数对比如下托管平台仓库要求自定义域名HTTPS国内访问速度GitHub Pages公开仓库支持自动一般不稳定Gitee Pages公开仓库支持自动快Cloudflare Pages连接 Git 仓库支持自动快偶尔波动最省事的方式是推 GitHub。首次在项目目录执行git init git add . git commit -m init blog git branch -M main git remote add origin https://github.com/你的用户名/你的仓库名.git git push -u origin main推送成功后进入仓库的 Settings - PagesSource 选Deploy from a branch分支选main目录选根目录保存后等待一两分钟博客就会出现在https://你的用户名.github.io/仓库名下。国内访问 GitHub Pages 速度不稳定想要稳定快速就选 Gitee Pages 或 Cloudflare Pages。Gitee Pages 需要先实名认证仓库转换成 Gitee Pages 服务后每次更新代码要在控制台手动点一次“更新”。Cloudflare Pages 国内访问大体顺畅不需要备案是技术博客圈子的常用方案。如果完全不想碰命令行也有静态托管服务支持直传文件夹但 Git 方式是主流建议还是花半小时熟悉基本命令——这属于早晚要补的一课。4. 个人博客 HTML 源码避坑路径、编码、兼容性三条主线代码能跑是前提跑起来不翻车才叫稳。这里把改博文、换主题过程中最容易出现的几类翻车事故整理出来每条都按“现象、原因、解决”写清楚。4.1 页面打开了但样式全丢现象浏览器能显示文字和图片但布局完全裸奔没有背景色、没有卡片圆角、导航横排也全部失效。原因最常见的是css/style.css的路径引用断了。比如把 index.html 直接从项目根目录复制到了 posts 子目录原来hrefcss/style.css是相对路径在 posts 目录里会去查找posts/css/style.css自然找不到。也有可能是本地预览时用file://协议直接打开而 CSS 文件内部有用绝对根路径引用的额外资源。解决确认 index.html 和 css 目录的相对关系。项目结构里 index.html 与 css、js、images 平级时用hrefcss/style.css如果 HTML 文件在二级目录里要写成../css/style.css。把网站部署上线后打开浏览器开发者工具F12切到 Network 面板刷新页面看有没有红色标红的样式请求只要 404 的 URL 出现在那里路径问题一目了然。提示改 HTML 内部引用路径时养成“从根目录视角推一遍”的习惯。站在目标 HTML 文件的位置看要引用的资源在哪个方向一级目录用./开头上一级用../开头这个思路比死记硬背可靠得多。4.2 中文文章标题全部变成问号或乱码现象浏览器里看文章列表、页面标题、摘要都是正常的但单独打开某篇文章中文变成一堆方块或问号。原因HTML 文件本身没有保存为 UTF-8 编码或者文件缺了meta charsetUTF-8声明。用 Windows 自带的记事本或者某些默认使用 GBK 编码的编辑器修改文件后保存时编码变了浏览器按 UTF-8 解析就会出乱码。解决设置编辑器默认保存编码为 UTF-8。VS Code 的右下角有“UTF-8”按钮点击后选择“Save with Encoding”并选择 UTF-8纯文本编辑器则可能需要在另存时手动选编码。改完之后确认 head 区有meta charsetUTF-8并且在 HTML 里不要出现charsetgb2312这样的旧声明。4.3 手机上看布局被挤压变形现象手机浏览器打开页面文字没有自动适应屏宽横向滚动条出现卡片充满整个屏幕但边距非常窄。原因缺 viewport 设置是头号嫌疑。没有meta nameviewport contentwidthdevice-width, initial-scale1.0这行移动端浏览器默认按 980 像素的虚拟画布渲染然后把页面整体缩小观感上就是字小、布局挤。另一种可能是媒体查询的断点没覆盖到当前机型比如只写了 768px 断点有些手机宽度超过这个值平板横屏也会不触发小屏样式。解决先确认 head 里 viewport 标签存在。再看媒体查询的断点是否合理——一般覆盖 360px 到 768px 区间就够用了常用断点可以设为 768px 一个中档断点。调样式时把浏览器窗口拖到窄宽度实时看效果比在真机上一遍遍刷新效率高。4.4 图片加载慢页面整体卡顿现象博客文章里插了几张大图打开时图片一点点从顶部往下加载页面滚动时明显掉帧甚至图片区域空白很久。原因图片没有经过压缩原图直接放进 images 目录。相机或设计稿导出的图片动辄 2MB 起步请求一个 2MB 的文件比请求 50KB 的文件慢几十倍多张大图一起加载带宽和内存双吃紧。也不排除图片尺寸远远超过了展示尺寸宽 4000 像素的图被 CSS 压缩显示成 600 像素浪费资源。解决文章配图在放入项目之前先压一轮。规则很简单图片显示宽度是 600 像素就导出 600 像素宽的图显示宽度是 1200 像素就导出 1200 像素。保存格式按需选摄影图用 JPEG截图和图形界面用 PNG 或 WebP。大小控制到 200KB 以下最稳。压缩工具用任何一个在线的都行或者用本地命令行工具批量处理# 已安装 ImageMagick 时批量压缩文件夹内所有 jpg mogrify -resize 1200x -quality 82 images/*.jpg-resize 1200x强制最大宽度 1200 像素高度等比例缩放-quality 82是 JPEG 压缩质量80 到 85 区间肉眼看不出明显劣化体积能减一半以上。图片尺寸和体积处理好之后再考虑要不要加懒加载——用loadinglazy属性让图片滚到视口附近才开始加载一页几十张图也不会卡。4.5 改了代码刷新页面没变化怀疑浏览器“记忆”了旧版本现象改完 CSS 或 JS刷新页面还是旧样式、旧交互控制台里也看不到报错。原因浏览器缓存了 CSS 和 JS 文件。静态文件通常带有缓存策略尤其部署到托管平台后平台会自动给静态资源打长缓存时间的标记。本地预览时也有小概率是编辑器的自动保存没触发改了但文件没写进磁盘。解决本地调试时强制刷新Windows 用 CtrlF5Mac 用 CmdShiftR这会绕过缓存重新拉资源。部署到线上后遇到这个问题处理方式是给资源加载加版本参数。比如link relstylesheet hrefcss/style.css?v20250106 script srcjs/main.js?v20250106/script?v后面跟日期或版本号参数变化后浏览器把它当作新 URL强制重新下载。这个习惯值得长期保持每次发布改一下版本号比让用户手动清缓存靠谱。还有一种情况Git 提交了但没推送到远端仓库线上是旧版本——检查本地 commit 和远程仓库的差异。5. 进阶玩法让静态博客自动生成文章列表上线前五项验证静态博客的短板是“文章得手写 HTML 卡片再塞进首页”。本节给一个轻量方案用原生 JS 配合一份 JSON 配置让首页文章列表自动渲染再从性能、SEO、链接三个维度做上线前的验证。一套流程走完这套模板就真正变成你自己的博客系统了。5.1 用一小段原生 JS 自动渲染文章索引思路是把文章元数据标题、链接、日期、分类、封面图、摘要放进一个data/posts.jsonindex.html 里的文章卡片容器留空页面加载后用fetch拉取 JSON循环拼出卡片 DOM 插入页面。新建data/posts.json与 index.html 平级目录[ { title: Nginx 配置踩坑记录, url: posts/nginx-config.html, date: 2024-11-20, category: 技术笔记, cover: images/cover-1.jpg, excerpt: 记录配置 Nginx 时的几个典型问题。 }, { title: 从零开始搭建个人博客, url: posts/blog-setup.html, date: 2024-12-01, category: 随笔, cover: images/cover-2.jpg, excerpt: 聊聊选型、写文章和部署的整体流程。 } ]这里每一项就是一个文章的展示字段后续加文章只需在数组里加一个对象。日期字段建议用YYYY-MM-DD这种可排序格式后面渲染时可以按 date 倒序排。然后在 js/main.js 里加一段渲染逻辑fetch(data/posts.json) .then(res { if (!res.ok) throw new Error(HTTP ${res.status}); return res.json(); }) .then(posts { const container document.querySelector(.posts-list); if (!container) return; const html posts.map(post article classpost-card div classpost-cover img src${post.cover} alt${post.title} /div div classpost-body span classpost-category${post.category}/span h2 classpost-title a href${post.url}${post.title}/a /h2 p classpost-excerpt${post.excerpt}/p div classpost-meta span classpost-date${post.date}/span /div /div /article ).join(); container.innerHTML html; }) .catch(err console.error(文章列表加载失败:, err));代码逻辑分三段第一步先fetchJSON 文件res.ok用于判断 HTTP 状态码非 2xx 直接抛错第二步拿到数组后遍历生成 HTML 模板字符串最后一次性把整段 HTML 塞进容器。用map加join()避免末尾多逗号比forEach拼接更干净。模板字符串里的${}要注意安全边界如果标题或摘要里带了引号、尖括号直接嵌进 HTML 可能破坏结构。三个防护习惯一是内容自己可控时保证 JSON 里不写script这类标签二是渲染前做一次字符转义三是在 index.html 预留容器时给一个空节点渲染失败也不影响页面主体。5.2 用脚本把文章数据抽成 JSON上面那段逻辑假设你手动维护 posts.json。文章少可以文章多了手写容易漏字段。更省力的方式是用 Node.js 脚本扫描文章目录自动生成 JSON。熟悉命令行的可以挂一个定时任务这里给出一个最小可用的脚本// scripts/gen-posts-json.js const fs require(fs); const path require(path); const postsDir path.join(__dirname, ../posts); const outputFile path.join(__dirname, ../data/posts.json); const posts fs.readdirSync(postsDir) .filter(file file.endsWith(.html)) .map(file { const fullPath path.join(postsDir, file); const content fs.readFileSync(fullPath, utf-8); // 从 HTML 文件中提取 title 和首个 meta namedescription const titleMatch content.match(/title([^])\/title/); const descMatch content.match(/meta namedescription content([^])/); const dateMatch content.match(/time datetime([^])/); return { title: titleMatch ? titleMatch[1] : file, excerpt: descMatch ? descMatch[1] : , date: dateMatch ? dateMatch[1] : , url: posts/${file} }; }) .sort((a, b) b.date.localeCompare(a.date)); fs.writeFileSync(outputFile, JSON.stringify(posts, null, 2)); console.log(已生成 ${posts.length} 篇文章的索引);运行方式node scripts/gen-posts-json.js脚本做的事情并不玄读 posts 目录下所有 .html 文件逐一用正则抽取title、description、time datetime字段缺了就给空字符串兜底按日期从新到旧排序最后写到 posts.json。文章分类、封面这些字段不在 HTML 里需要额外约定写进每个文章的页面内或者干脆在脚本里用一个规则表映射文件名到分类。这种脚本的好处是新文章写好后跑一次首页列表就自动更新不用手动改 index.html。5.3 部署后必做的五项验证部署完成并不能代表万事大吉上线后按下面五条逐一过一遍基本能保证常态可用第一选一篇文章走通整个访问链路。点击首页卡片进入文章详情页确认文章页的 CSS 也正常。有些模板详情页是单独的设计漏引用 CSS 文件会让文章页裸奔。地址栏里的 URL 如果带.html后缀属于正常静态页面如果显示posts/结尾没有扩展名可能是平台做了美化路由后续上传文件时注意保持目录结构一致。第二检查图片引用是否全部可访问。进入文章详情页打开开发者工具或直接右键图片检查逐个确认图片来源是正常 200 还是 404。常见问题是图片存放在 images 根目录而文章在 posts 子目录引用路径写成了images/xx.jpg这里必须写成../images/xx.jpg。第三确认网站标题和描述正确显示。浏览器标签页上显示的标题就是title里的内容。用微信或者钉钉把链接发给同事看聊天窗口里的预览卡片是否显示了正确的标题、描述和缩略图。没有缩略图时在 head 区添加一张og:image的 meta 标签指向封面图社交平台一般会有缓存第一次预览不生效过几分钟再看。第四跑一次基础 SEO 检查。把线上 URL 贴到搜索引擎的抓取模拟工具里确认能拿到 200 状态和页面内容。重点确认首页title不要和文章页重复博客标题加上文章标题是更合理的组合比如文章标题 - 博客名这种结构。第五全站走一遍小屏适配。用手机或开发者工具的手机模拟模式打开首页、文章页、归档页各扫一眼重点看导航、卡片、图片有没有横向溢出。移动端访问占比在技术圈子里并不低这步不要省。这套模板用顺手之后建议给自己固定一套发布流程写完文章 HTML 文件放对目录跑一次生成 JSON 的脚本本地起服务预览一遍推 Git上线后再跑一遍上面五项验证。我做这套流程用了大半年中间翻过车——有一阵往 JSON 里塞了未转义的双引号整个首页文章列表直接空白控制台报语法错误。从那以后每次更新 posts.json 后我都要在浏览器控制台确认 fetch 返回的数组长度和文章数对得上再继续做别的。这已经是刻进肌肉记忆的习惯希望这套流程也能帮到你少踩几个坑。本文还有配套的精品资源点击获取
返回列表