Markdown 简历生成器:左边写、右边出预览

举报
茉莉风铃 发表于 2026/10/06 19:46:27 2026/10/06
【摘要】 用 React18 + TypeScript + Vite + markdown-it 写 Markdown 简历生成器:左边受控 textarea 写、右边 md.render 实时预览、window.print 导出 PDF。含代码与 XSS 防护(html:false)、打印样式等注意点,纯前端零后端。

一、背景:写简历,不如用 Markdown 写

做技术的人,大多熟 Markdown——标题、列表、加粗、代码块,敲起来比拖富文本编辑器顺手,还能进版本管理。简历本质就是一份带层级结构的文档,用 Markdown 写再合适不过:左边写源文本,右边实时渲染成排版好的预览,满意了导出 PDF 直接投。

本文用 React 18 + TypeScript + Vite 写一个小工具:左边一个文本框写 Markdown,右边用 markdown-it 渲染成 HTML 实时预览,带打印导出。全程纯前端、零后端,写完构建成静态站点就能用。它把"React 受控组件 + TS 类型 + Markdown 解析"这件日常组合练了一遍,适合想熟悉 React + TS 的人照着做。

二、为什么加 TypeScript

纯 JavaScript 写这种小工具也能跑,但加 TS 有几个实在好处:组件 props、状态、事件对象都有类型提示,写的时候 IDE 就告诉你拼错字段;markdown-it 的插件、配置项类型明确,少踩"传了不存在的选项"的坑;改代码时类型检查能拦住一大批低级错误。对简历生成器这种"输入格式固定、渲染逻辑清晰"的工具,TS 的投入产出比很高。

三、核心:Markdown 解析就一行

渲染的活其实全在 markdown-it 上,自己几乎不用写解析:

import MarkdownIt from 'markdown-it'
const md = new MarkdownIt({ html: false, linkify: true, breaks: true })

function Preview({ src }: { src: string }) {
  const html = md.render(src)          // Markdown 字符串 → HTML 字符串
  return <div dangerouslySetInnerHTML={{ __html: html }} />
}

md.render(src) 一行就把 Markdown 转成 HTML 字符串,然后塞进 dangerouslySetInnerHTML。这里有个安全设置:html: false 表示不允许 Markdown 里写原始 HTML,防止有人(或未来的你)在简历源里塞 <script> 被渲染执行,造成 XSS。未知来源的 Markdown 一定要关掉 html 选项,这是安全底线。linkify: true 让裸链接自动可点,breaks: true 让单换行也生效,更符合写作直觉。

四、编辑器:受控文本框 + 实时同步

左边编辑器就是一个受控 textarea,值变化时更新状态、触发预览重渲染:

import { useState } from 'react'

function App() {
  const [src, setSrc] = useState('# 张三\n前端工程师\n\n## 技能\n- React\n- TypeScript')
  return (
    <div className="layout">
      <textarea value={src} onChange={e => setSrc(e.target.value)} />
      <Preview src={src} />
    </div>
  )
}

textarea 用 value + onChange 受控,输入即更新 src,Preview 拿到新 src 重新 md.render,于是"左边敲、右边变"的实时预览就实现了。useState 的初始值放一份简历模板,打开就有内容可看。TS 在这里给 src、setSrc 推导出 string 类型,组件接收的 src prop 也显式标注 { src: string },类型清晰。

五、导出:打印成 PDF

预览满意了要导出。最简单可靠的方式是利用浏览器打印:给预览区套一份打印样式,点"导出"调 window.print(),在打印对话框里选"存为 PDF"。

function exportPdf() { window.print() }

配合一份 @media print 的 CSS:隐藏编辑器、只显示预览区、设好页边距和字体,打印出来的 PDF 就是干净的简历版式。比引入重型导出库轻,且效果由浏览器原生保证。若要更精细的排版(分页控制、页眉),再在打印样式里细化。打印样式的写法以 CSS 规范为准,这里不展开。
image.png

六、几个注意点

第一,XSS 那道关。再次强调 html: false。如果将来你确实需要简历里嵌自定义 HTML(比如特殊排版),至少做白名单过滤,别直接 html: true 放行一切,否则渲染任意 Markdown 就等同渲染任意 HTML。

第二,样式隔离。markdown-it 只产出 HTML 结构(h1/h2/ul/p),具体长相靠你写的 CSS。建议给预览容器一个独立 class(如 .preview),样式只作用域内,别让简历样式污染页面其它部分。

第三,图片与相对路径。如果简历里引用本地图片,纯前端工具没有"上传托管"概念,图片要么用外链(图床/CDN),要么用 base64 内联。用外链要注意链接失效风险;base64 会让源文件变大。按你发布方式选。

第四,默认模板要有。初始 src 放一份结构清晰的模板(个人信息/技能/经历/项目),用户打开就有骨架,改字就行,体验比空白框好得多。

第五,TS 严格模式。开启 strict 后,事件对象、可能为空的字段都要显式处理,开始略烦但能挡住很多运行期错误。小工具也值得开。

七、小结

Markdown 简历生成器,技术含量几乎全在"markdown-it 一行 render + 受控文本框实时同步":左边 textarea 受控、值变即重渲染、右边 md.render 出 HTML。加 TS 让 props 和状态类型清楚、少低级错;html: false 守住 XSS 底线;导出靠 window.print() + 打印样式,零依赖。纯前端构建成静态站点即用。这类"输入→实时渲染"的小工具范式,套到笔记、文档预览都通用。markdown-it 配置项和打印样式以各自文档为准。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。