Vue多页应用转单页:Vite构建模式切换实战
早期折腾一个管理系统时遇到过特别拧巴的构建需求项目本身是典型的多页 Vue 应用好几个页面各司其职但其中一个渠道方只给了一个入口要求所有页面必须以“单页面应用”的方式打包交付而且要能同时在测试和正式环境下切换。当时第一反应是“这不就是要我推翻重写吗”后来想通了——问题的本质不是“重写业务”而是控制“构建形态”。一套代码通过打包模式的选择既可以打成多页结构也可以打成单页结构这个思路落地之后工程上的收益比想象的大得多。这篇文章会把完整方案拆开讲清楚包含两条改造路线、模式矩阵的编排方式以及一整套能直接复用的 Vite 配置。无论你是要把存量多页项目接入只支持单入口的托管平台还是纯粹想降低多页项目的部署复杂度这篇内容基本够用。1. 场景与痛点什么项目会碰到“多页打成单页”的需求1.1 一次真实的改造需求先说说我遇到的状况。某公司内部系统早期为了方便独立部署把几个功能模块拆成了独立页面登录页、工作台、数据报表页各自有各自的入口文件构建后输出多个 HTML。这种结构单独验收非常舒服某个模块发版不影响其他模块。但有个新渠道只提供一个 URL 入口所有功能都要从这个 URL 进去本质上一个页面壳子把路由接完。硬着头皮改业务代码不现实页面组件、权限逻辑、接口层全是现成的直接复用是最好的做法。所以我把问题收敛成一个构建层面的目标同一套源码、同一套业务逻辑通过切换打包模式分别产出“多页产物”和“单页产物”。这样平时内部部署继续用多页外部渠道用单页两边逻辑保持一致只差在打包这个环节。类似需求其实很常见。电商活动页需要复用主站组件但要以独立 H5 上线嵌入第三方容器时对方只允许绑定一个地址还有 CDN 静态托管只认单入口的场景。只要碰到这些你现在维护的 MPA 大礼包就会显得很尴尬。1.2 多页与单页在构建层的本质差异要理解为什么能通过打包模式解决得先弄明白两者在构建产物上的差别。多页应用MPA的构建结果通常是dist-mpa/ index.html login.html report.html assets/ index-xxx.js login-xxx.js report-xxx.js每个 HTML 对应一个独立入口用户访问哪个地址就加载哪个页面。而单页应用SPA的构建结果通常只有一个dist-spa/ index.html assets/ index-xxx.js chunk-xxx.js所有业务逻辑都从同一个入口加载路由切换在前端完成后端只需要把未知路径回退到 index.html 即可。从源码角度来说MPA 和 SPA 之间就差两步一是入口文件怎么聚合二是路由是怎么组织的。多页应用里每个页面可能都有独立的 createApp 挂载单页应用则只有一个 app 实例加一套统一路由表。明白了这个差异你就会发现“多页转单页”真正要动的只有构建配置和入口编排业务组件可以原封不动。2. 整体设计两条改造路线与打包模式矩阵2.1 路线一入口聚合改造这是最直接、成本最低的一种方案。多页应用中每个页面都有一份类似这样的入口代码// src/pages/login/main.js import { createApp } from vue import App from ./App.vue createApp(App).mount(#app)入口聚合的思路是把这些散落各处的页面入口统一替换成一个总入口在总入口里由 vue-router 根据 URL 决定渲染哪个页面组件。// src/main.js import { createApp } from vue import { createRouter, createWebHashHistory } from vue-router import App from ./App.vue const routes [ { path: /login, component: () import(/pages/login/App.vue) }, { path: /home, component: () import(/pages/home/App.vue) }, { path: /report, component: () import(/pages/report/App.vue) }, { path: /, redirect: /home } ] const router createRouter({ history: createWebHashHistory(), routes }) createApp(App).use(router).mount(#app)App.vue 里放一个 router-view 就完事template router-view / /template原来的每个页面 Application 组件现在全变成了路由组件这就是整个改造的核心。单页模式跑起来后你会发现原本需要跳转 iframe 或者新开标签页的页面关系现在变成了纯前端路由切换用户感知上是完整的 SPA 体验。2.2 路线二路由化改造如果项目是纯 Vue 3 Vite 的新代码或者本来就有一定程度的组件化基础那更推荐“路由化改造”这条路。它的核心在于把“每个页面入口”从“物理入口”转换为“逻辑入口”。也就是构建层面仍然维持多入口但当一个特殊模式下构建逻辑会忽略掉这些物理入口统一只取一个聚合路由入口。一条比较优雅的做法是同时保留两种路由模式多页模式下用 createWebHistory单页模式下用 createWebHashHistory。这样单页部署在二级目录下时不需要服务端回退配置也能正常工作。const history import.meta.env.VITE_ROUTER_MODE hash ? createWebHashHistory() : createWebHistory(import.meta.env.VITE_BASE_PATH || /)两种方案没有绝对优劣。入口聚合适合“页面之间本来就是平行关系”的系统路由化改造适合那种有可能继续扩展成完整 SPA 的项目。我个人用第二种多一些因为切换代价更低随时通过环境变量回到多页。2.3 打包模式的矩阵构建形态 × 运行环境这里需要把“模式”这个概念拆开看。一个工程里其实有两类模式一类是构建模式决定打出多页还是单页另一类是运行环境模式决定代码里走测试接口还是正式接口。于是可以组合出四类打包需求构建形态运行环境用途多页测试内部联调、临时演示多页正式常规正式部署单页测试渠道方测试环境验证单页正式渠道方正式环境交付在 Vite 里构建模式通过--mode参数控制环境变量通过.env文件控制。这两层可以叠加最终生成状态完全可控的产物。3. 实操Vite 环境下的一套完整配置3.1 改造前的项目结构基线假设项目结构如下src/ pages/ login/ App.vue home/ App.vue report/ App.vue router/ index.js api/ request.js components/ BaseLayout.vue assets/ index.html package.json vite.config.js这是很常规的多页结构。传统 MPA 会在根目录放多个 HTML或者通过 Vite 插件生成多个 HTML下面我先按“最终只保留一个 index.html通过模式切换入口”的思路来配置。3.2 vite.config 按模式切换的写法单独看这份配置它解决了从哪个入口构建的问题// vite.config.js import { defineConfig, loadEnv } from vite import vue from vitejs/plugin-vue import { resolve } from path import { fileURLToPath, URL } from node:url export default defineConfig(({ command, mode }) { const env loadEnv(mode, process.cwd(), ) const isMPA env.VITE_BUILD_FORMAT mpa // 多页入口保留物理差异单页入口统一收敛到 main.js const buildInput isMPA ? { login: resolve(__dirname, src/pages/login/main.js), home: resolve(__dirname, src/pages/home/main.js), report: resolve(__dirname, src/pages/report/main.js) } : { main: resolve(__dirname, src/main.js) } return { plugins: [vue()], base: env.VITE_BASE_PATH || /, resolve: { alias: { : fileURLToPath(new URL(./src, import.meta.url)) } }, build: { outDir: isMPA ? dist-mpa : dist-spa, emptyOutDir: true, rollupOptions: { input: buildInput, output: { manualChunks: { vendor: [vue, vue-router, pinia] } } } } } })有几个细节特别容易踩。loadEnv的第三个参数传是为了把所有前缀的变量都读进 env否则按默认行为只会读取VITE_开头的变量。第三个参数保持为空配合VITE_BUILD_FORMAT这个名字是没问题的。outDir区分成dist-mpa和dist-spa也很重要。第一次改的时候我因为没换输出目录导致一种模式的旧文件残留到了另一种模式的产物里。emptyOutDir虽然会清空但清的是同一个目录。把两个形态的产物分开放CI 里比对构建结果也更方便。3.3 多页模式与单页模式下路由的处理Vite 的配置只保证了入口的差别路由还需要让同一套代码适配两种模式。先建一份环境变量文件# .env.spa VITE_BUILD_FORMATspa VITE_ROUTER_MODEhash VITE_BASE_PATH/# .env.mpa VITE_BUILD_FORMATmpa VITE_ROUTER_MODEhistory VITE_BASE_PATH/multi-page/然后在路由入口里读取这些变量// src/router/index.js import { createRouter, createWebHistory, createWebHashHistory } from vue-router const routes [ { path: /login, component: () import(/pages/login/App.vue) }, { path: /home, component: () import(/pages/home/App.vue) }, { path: /report, component: () import(/pages/report/App.vue) }, { path: /, redirect: /home } ] const historyMode import.meta.env.VITE_ROUTER_MODE hash ? createWebHashHistory() : createWebHistory(import.meta.env.VITE_BASE_PATH) const router createRouter({ history: historyMode, routes }) export default router注意createWebHistory要传入部署基础路径也就是VITE_BASE_PATH。如果不传Vite 构建时即使把 base 配成了/multi-page/路由内部依然会用/来解析地址刷新子路由时会直接 404。3.4 package.json 的脚本编排接下来就是打包模式真正落地的关键一步——脚本编排{ scripts: { dev: vite, build: vite build, build:mpa: vite build --mode mpa, build:spa: vite build --mode spa, build:mpa:test: vite build --mode mpa-test, build:spa:test: vite build --mode spa-test, build:mpa:prod: vite build --mode mpa-prod, build:spa:prod: vite build --mode spa-prod } }配合环境文件# .env.mpa-test VITE_BUILD_FORMATmpa VITE_ROUTER_MODEhistory VITE_ENVtest VITE_API_BASE/test-api# .env.spa-prod VITE_BUILD_FORMATspa VITE_ROUTER_MODEhash VITE_ENVprod VITE_API_BASE/prod-api这样只需要在 CI 或命令行里选择不同的 build 脚本就能拿到对应形态、对应环境的产物。整个过程不需要手改任何源码。4. 关键细节base 路径、懒加载与公共依赖拆分4.1 base 路径为什么是重中之重“多页转单页”最容易翻车的地方就是静态资源路径。多页模式部署在/multi-page/下页面里引用的图片、JS、CSS 都是相对路径单页模式部署在根路径或二级目录下两者对路径解析方式完全不同。我踩过的坑是这样的第一次打单页包用的是默认/作为 base结果渠道方部署在/app/h5/这种二级路径打开后所有资源都 404。排查半天发现 HTML 里 script 的 src 指向/assets/index-xxx.js浏览器把它当成域名根目录下的文件去请求了。解决方案就是在.env.spa里显式指定VITE_BASE_PATH/app/h5/然后在 vite.config 中把base: env.VITE_BASE_PATH替进去。更稳的做法是直接用相对路径base: ./让所有资源都从当前 HTML 所在目录解析但要注意的是相对 base 在 history 路由 懒加载场景下子页面刷新时可能会出现 chunk 路径错位所以生产环境我还是建议使用绝对路径配合部署平台的实际访问路径。4.2 懒加载与代码分割的处理多页应用因为入口天然隔离每个页面打包后体积相对可控。一旦并到单页包里如果所有组件一下子全挂到主 bundle 里首屏会很难看动辄好几 MB 的 JS。路由组件我全部用动态 importconst routes [ { path: /login, component: () import(/pages/login/App.vue) }, { path: /home, component: () import(/pages/home/App.vue) }, { path: /report, component: () import(/pages/report/App.vue) } ]Vite 构建时会自动为每个动态 import 生成独立 chunk。加上manualChunks把依赖框架单独拎出来能显著提升缓存命中率。manualChunks: { vendor: [vue, vue-router, pinia] }如果项目里还引用了图表库、富文本编辑器这类重型依赖建议进一步拆出charts、editor这样的独立 chunk。这样即使报表页面很重访问登录页时也不会加载这些无关代码。4.3 全局样式与状态管理的统一多页应用每个页面通常都有自己的全局样式入口比如页面 A 里给 body 设置了背景色页面 B 里又给 body 设置了另一个背景色。单页集成后这些全局样式会在同一时刻全部生效后加载的样式会覆盖先加载的样式表现出来就是页面间跳转时样式“串味”。处理思路可以分三步把页面特有的样式收敛到组件作用域内尽量使用scoped。真正的全局样式只保留 reset 类和主题类。如果某些页面有必须在全局生效的样式给根节点加限定前缀例如.report-page body。状态管理方面多页应用各页面可能有独立的 store 实例单页化后需要把 store 统一为一个根 store。这里最省力的做法是只保留一个全局 store页面级状态用模块拆分别搞多个 createStore。import { createPinia } from pinia import { useUserStore } from ./stores/user import { useReportStore } from ./stores/report const pinia createPinia() app.use(pinia)统一之后页面跳转时不会有重复的初始化逻辑也避免多个 store 实例互相抢内存。5. 常见问题排查与避坑清单5.1 常见问题速查表现象大概率原因解决办法单页包打开资源全部 404base 路径没配置或配置不对确认VITE_BASE_PATH与部署路径一致检查 vite.config 里的base子路由刷新后 404history 模式缺少服务端回退单页模式下改用 hash 路由或配置服务端把未知路径回退到 index.html页面跳转后样式错乱、互相覆盖多页的全局样式在单页里同时生效收敛为页面级 scoped 样式保留一份全局 reset首屏加载体积暴涨没有动态 import 或没有拆 vendor路由组件全部改() import()配置manualChunks接口请求路径不对环境变量没正确加载检查.env.*文件名是否和--mode参数对应动态 import 的 chunk 加载失败相对 base 二级路由 history 模式组合踩雷要么用绝对 base要么用 hash 模式构建后某些图片路径变成data:image资源小于assetsInlineLimit被内联调整build.assetsInlineLimit或显式配置资源输出路径这张表基本覆盖了我几次实操中遇到的全部问题。每次出现诡异问题先别急着翻代码用排除法定位到“构建时路径问题”还是“运行时路由问题”会快很多。5.2 关于单页打包的三个经验教训第一个教训别让构建模式污染业务代码。凡是需要区分单页和多页的地方都要通过 import.meta.env 读取变量而不是写死判断。这样后续调整模式逻辑只动配置不动业务。如果业务代码里出现了if (isMpa)这种三处以上引用趁早抽成环境配置对象// src/config/index.js export default { buildFormat: import.meta.env.VITE_BUILD_FORMAT, routerMode: import.meta.env.VITE_ROUTER_MODE, apiBase: import.meta.env.VITE_API_BASE }第二个教训永远保持一个模式是“默认安全”的。我在 package.json 里把build默认指到build:mpa这样即使某次 CI 忘了选模式产出的也是原先最熟悉的多页结构不至于直接覆盖线上单页产物。第三个教训单页化之后多页模式也要定期跑一次构建。这是为了确保两套模式都能正常出包。我身边有同事因为长期只验证单页包等回归多页构建时才发现入口文件路径已经被改掉编译直接报错。维护两套入口就要保证两套入口都被持续验证。6. 构建产物验证与性能监控6.1 产物结构对比怎么查打包完成之后建议先看产物结构不要急着部署。用tree或者直接看文件管理器多页模式产物大致长这样dist-mpa/ index.html login.html report.html assets/ index-xxx.js login-xxx.js report-xxx.js vendor-xxx.js单页模式产物大致长这样dist-spa/ index.html assets/ index-xxx.js login-xxx.js report-xxx.js vendor-xxx.js重点确认两件事单页产物里是否只有一份 index.html。原来三个页面的业务 chunk 是否都以懒加载 chunk 的形式存在于 assets 目录中。如果单页产物里出现了多个 HTML 文件说明构建配置里的 input 仍然被当成多入口解析了。这种情况下优先检查VITE_BUILD_FORMATspa是否真的被 loadEnv 读到。6.2 体积监控的常用手段单页包上路之前最好对体积有个底。我习惯在发包前跑一次npx vite build --mode spa-prod然后看终端输出的文件体积列表。也可以加vite-plugin-compression做 gzip 或 brotli 预压缩配合静态服务层的压缩策略首屏可以再快一些。一个可参考的阀值是单页包 gzip 后总 JS 不超过 300KB 算比较健康超过 500KB 就需要认真优化。如果项目里引入了大型依赖优先检查是不是整包引进了某个库// 避免这种写法 import * as echarts from echarts // 改为按需引入 import { LineChart } from echarts/charts这种优化效果非常明显配合路由懒加载一个原来 2MB 的单页包能降到 400KB 左右。踩过几次坑之后的总结我个人在实际操作中的体会是多页转单页这件事真正的复杂度不在于“改代码”而在于理顺“构建形态 × 运行环境”的切换机制。只要把入口、路由、base 路径这三点抽成由环境变量驱动的配置项后续增加一个新页面到单页包也只是往路由表里加一行的事情。最后再分享一个小经验第一次切换模式的时候不要直接在生产环境验证。先在本地分别跑一次build:mpa和build:spa把两个产物目录同时启动起来用两个端口对比着访问。这样哪边出问题看一眼是哪份产物的问题定位起来会非常清晰。这套流程稳定下来之后你会发现“一套代码多套形态”不再是不可维护的怪需求反而成了项目交付时一个很灵活的能力。

相关新闻

Java二叉搜索树从原理到工业实践全解析

Java二叉搜索树从原理到工业实践全解析

1. 项目概述:为什么树结构是Java开发者绕不开的“分水岭”刚带完一届校招培训,有个现象特别明显:能熟练写链表、栈、队列的新人不少,但一提到二叉搜索树的删除逻辑,八成会卡在“双子节点怎么处理”上;问红黑…

2026/10/13 13:19:52 阅读更多 →
Fabric 2.5多组织农产品溯源系统:可运行毕设源码包

Fabric 2.5多组织农产品溯源系统:可运行毕设源码包

简介:本资源是一套基于Hyperledger Fabric区块链框架构建的农产品通用溯源系统完整实现,面向计算机类专业本科生、研究生及初入区块链领域的开发者,解决传统农产品流通中信息不透明、数据易篡改、多方协作难等核心问题,适用于毕业…

2026/10/13 13:19:52 阅读更多 →
Java校内二手交易系统毕设全攻略:从Spring Boot到小程序实战

Java校内二手交易系统毕设全攻略:从Spring Boot到小程序实战

1. 项目定位与需求拆解:为什么“校内二手交易”是最稳妥的毕设选题每年到二月底三月初,总有一批计算机专业的大四学生开始焦虑毕业设计选题。Java校内二手交易市场这套系统,我前前后后带人做过不下二十个版本,从最早SSH框架的JSP项…

2026/10/13 13:19:52 阅读更多 →

最新新闻

统一多模型API网关litellm实战:从配置到生产部署

统一多模型API网关litellm实战:从配置到生产部署

这段时间我一直在做一个内部的多模型调度平台,见得最多的一个词就是 litellm。它不是一个具体的大模型,也不是某个框架的插件,而是一个把各种模型 API 统一成一套格式的网关层工具。说白了,你只需要学会接一个服务,剩下…

2026/10/13 13:58:46 阅读更多 →
高中化学实验题满分攻略:从操作原理到误差分析的系统梳理

高中化学实验题满分攻略:从操作原理到误差分析的系统梳理

1. 为什么高中化学实验题总是“看着全会、做题全废”先抛个问题:你有没有过这种经历——课本上的实验都读了一遍,氯气的实验室制法、氨气的喷泉实验、酯化反应的装置图,看着都觉得挺简单,可一到考试,装置图给你一个洗气…

2026/10/13 13:58:46 阅读更多 →
AI写代码的质量保卫战:规范、评审与风险测试三重防线

AI写代码的质量保卫战:规范、评审与风险测试三重防线

1. 这不是又一个“AI写代码”的热闹话题,而是工程团队正在真实发生的质量保卫战最近在几个技术社区和内部分享会上,我反复听到同一个问题:“我们上了Copilot、接入了CodeWhisperer、也试了各种本地大模型,但代码质量没变好&#x…

2026/10/13 13:58:46 阅读更多 →
PyCharm安装配置避坑指南:跨平台解释器绑定与IDE工程化预检

PyCharm安装配置避坑指南:跨平台解释器绑定与IDE工程化预检

简介:本资源是一份面向Python初学者与转行开发者的PyCharm零基础安装与入门配置指南,聚焦解决“不会装、不敢用、配不熟”三大实操痛点。PDF文档结构清晰,完整覆盖Windows、macOS、Linux三大主流系统下的下载选择、分步安装、首次配置&#x…

2026/10/13 13:58:46 阅读更多 →
SpringBoot+Vue+SpringCloud微服务实战:社区帮扶平台从单体重构到分布式

SpringBoot+Vue+SpringCloud微服务实战:社区帮扶平台从单体重构到分布式

前阵子帮老家社区做了一个邻里互帮互助的小平台,一开始就打算用单体应用糊弄过去,结果需求一多彻底压不住——又要搞门户展示、又要做帮扶工单流转、还要上可视化大屏给街道看数据,再加上志愿者积分、公告通知、用户认证这些模块,…

2026/10/13 13:58:46 阅读更多 →
PCL 1.13.0 与 Qt 6 集成实战:从 CMake 到点云可视化

PCL 1.13.0 与 Qt 6 集成实战:从 CMake 到点云可视化

简介:面向需要在Qt6框架中集成PCL 1.13.0进行点云处理开发的工程师与研究者,这份资源提供了完整的PCL编译产物与配套依赖。包内含约2.4万个文件,以hpp/h头文件、lib静态库、dll动态库及cmake配置文件为主,另含3rdParty第三方依赖、…

2026/10/13 13:57:45 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →