# softresume **Repository Path**: csxlin/softresume ## Basic Information - **Project Name**: softresume - **Description**: 免费开源的在线简历制作工具 | Vue 3 + Vite 单文件应用 | 19 套模板 · 7 种主题色 · 富文本编辑 · 一键导出 A4 PDF | 无需注册,数据本地存储 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: https://qing-resume-builder.app.workbuddy.host - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2026-11-03 - **Last Updated**: 2026-11-05 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 轻简历 SoftResume
[![在线使用](https://img.shields.io/badge/%F0%9F%9A%80-%E5%9C%A8%E7%BA%BF%E4%BD%BF%E7%94%A8-2f6bff)](https://qing-resume-builder.app.workbuddy.host/?sharecode=2PFJEBOAWE) [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](./LICENSE) [![Vue 3](https://img.shields.io/badge/Vue-3.x-42b883)](https://v3.vuejs.org/) ![Stars](https://gitee.com/csxlin/softresume/badge/star.svg?theme=gvp) 免费、开源、无需注册的在线简历制作工具。打开即用,数据只存在浏览器本地,一键导出 A4 PDF。
## ✨ 在线体验 **[👉 https://qing-resume-builder.app.workbuddy.host](https://qing-resume-builder.app.workbuddy.host/?sharecode=2PFJEBOAWE)** 无需注册、无需安装,打开即写;也支持下载仓库中的 `index.html` 直接双击离线使用。 ## 📋 功能特性 - **19 套模板**:经典专业 / 时间轴 / 商务横幅 / 现代侧栏 / 极简大字 / 雅致衬线 / 深色侧栏 / 右侧栏 / 双栏紧凑 / 卡片板块 / 瑞士网格 / 渐变横幅 / 日期左列 / 序号章节 / 照片头版 / 杂志衬线 / 极简ATS / 色块头版 / 清新圆角(版式家族参考 Awesome-CV、moderncv、AltaCV、Jake's Resume 等开源模板) - **主题随心配**:7 种精选主题色 + 自定义取色盘;19 种中英文字体;三档字号、三档行距 - **一个模块 = 一个富文本框**:加粗、斜体、下划线、删除线、圆点 / 编号 / 普通段落、Tab 缩进、局部换字体,都是 Word 式的段落编辑 - **智能一页**:内容超出一页时自动缩小字号压到一页,导出 PDF 不用手动调 - **头像处理**:上传后可裁剪、可切方形 / 圆形 - **多简历管理**:多份简历分别保存,支持导入 / 导出 JSON 备份 - **打印预览**:直接调起浏览器打印界面,导出 A4 PDF ## 技术栈 Vue 3 + Vite + Pinia,零后端、零外部请求。构建产物是**单个 index.html**([vite-plugin-singlefile](https://github.com/richardtallent/vite-plugin-singlefile) 把 JS/CSS 全部内联),所以既可以直接双击打开,也可以丢到任意静态托管。 ## 开发 ```bash npm install npm run dev # http://localhost:5178(开发入口 src/index.html) npm run build # 产出 dist/index.html,并同步一份到根目录 index.html npm run preview # 本地预览构建产物 ``` > 根目录的 `index.html` 是构建产物(文件头有标注),不要手改;开发用的模板是 `src/index.html`。 ## 目录结构 ``` index.html ★ 构建产物(单文件成品),已可双击打开 / 直接发布 vite.config.js Vite root 指向 src,构建后自动把成品同步到根目录 src/ ├── index.html 开发入口模板 ├── main.js 入口:注册 Pinia + 引入分层样式 ├── App.vue 三段式布局:顶栏 / 编辑面板 / 预览 ├── constants/ 纯数据:板块元信息、字体表、模板与配色、图标 │ ├── sections.js 新增一个板块,只需在这里加一项 │ ├── fonts.js 字体清单 + 分组 + fontStackOf() │ ├── templates.js 模板 / 配色 / 字号 / 间距 / A4 常量 │ └── icons.js 联系方式图标与字段顺序 ├── lib/ 与框架无关的纯逻辑,可单独复用、单测 │ ├── utils.js esc / debounce / parseDate / 颜色混合 … │ ├── bind.js 短路径绑定(work.items.0.company → sections.…) │ ├── richtext.js 富文本白名单清洗、结构规整、纯文本镜像 │ ├── caret.js 光标 / 段落级操作(缩进、选区套格式) │ ├── listOps.js 圆点 / 编号 / 普通段落三态互转 │ ├── image.js 图片压缩、裁剪导出 │ └── print.js 打印:临时改文档标题 ├── model/ │ ├── resume.js 数据模型 + 深合并 + 老数据迁移 │ └── sample.js 示例简历 ├── stores/ │ ├── resume.js Pinia:多简历、字段写入、自动保存、导入导出 │ └── ui.js 折叠状态、预览↔编辑器定位联动 ├── composables/ │ ├── useRteToolbar.js 浮动工具栏(单例,含定位与格式命令) │ └── useCropper.js 头像裁剪(单例) ├── components/ │ ├── AppTopBar.vue 顶栏 │ ├── DocSwitcher.vue 多简历切换面板 │ ├── EditorPanel.vue 左侧面板 + 拖拽排序 │ ├── cards/ 样式设置 / 基本信息 / 求职意向 / 板块卡片 / 条目表单 │ ├── preview/ A4 纸面、头部、板块、条目、单行字段、富文本区 │ ├── RteToolbar.vue 富文本工具栏 │ ├── CropperDialog.vue 裁剪弹窗 │ └── ui/ 分段选择器、模板缩略图 └── styles/ 按区域拆分的 CSS(base / topbar / layout / editor / resume / templates / toolbar / cropper / print) ``` ## 几个关键设计 **数据模型**:一份简历 = `docs[i].data`,结构见 `model/resume.js` 的 `defaultState()`。每个富文本块存两份:`descHtml`(结构)+ `desc`(纯文本镜像,供左侧 textarea 与搜索使用),老数据的 `descRich` / `rich` 由 `legacyToHtml()` 惰性迁移。 **可编辑字段不参与 diff**:预览里的可编辑元素(`InlineField` / `RichArea`)内部自己维护 DOM,只在「值变化且未聚焦」时重绘。否则每次 keystroke 回写状态都会重建文本节点,光标就跳了。这是把 contenteditable 放进响应式框架里最容易踩的坑。 **一个模块 = 一个 contenteditable**:段落、列表由浏览器原生行为产生(Enter 新建 li 并继承缩进),我们只补浏览器做不好的部分:Tab 整块缩进、列表类型互转、空列表项退格兜底。所有 HTML 落库前都过 `sanitizeRichHtml()` 白名单。 **自动保存**:Pinia 的 `$subscribe` 深度监听 + 400ms 防抖写 localStorage,切换简历 / 导入前会 `flushNow()` 立即落盘。 **打印**:`@page A4` + 打印时隐藏顶栏 / 编辑面板 / 辅助线与占位提示,纸面宽度改 210mm,页数由真实内容高度决定;「一页」开关会在超页时按 4.5% 步进缩小字号。 ## 部署 构建产物是单文件,丢哪儿都能跑: ```bash npm run build # 根目录 index.html(与 dist/index.html 同内容)上传到任意静态托管均可 # Gitee Pages / Nginx / OSS / Vercel / Cloudflare Pages 都只是「放一个 html 文件」 ``` 静态托管方(含 workbuddy 应用发布)直接把项目根目录当站点根即可,因为根目录的 `index.html` 就是成品;不需要在服务器上 `npm install`。 ## 数据与隐私 所有内容都在 `localStorage`(键名 `qingresume_docs_v1`),不上传任何服务器。换设备/换浏览器请用「导出JSON」备份再「导入」。 ## 版本说明 `v1.0-single-file` 标签是重构前的单文件版本(一个 2700 行的 index.html),保留在 git 历史里便于对照: ```bash git show v1.0-single-file:index.html > legacy.html ``` ## License MIT