# 简历制作模块
回顾一下现在的文件结构,在上一节时,我们将常用的组件进行抽离封装,对类型进行了约束,添加了 templates 模版文件夹,用于存放所有模版,新增 resumeModel 定义用户简历信息的数据字段。
万事俱备,接下来正式进入到简历制作环节,话不多说,让我们动手实践吧~
# 简历入口实现
我们将简历制作的页面拆分为三大块,分别为 头部操作区
、 简历内容展示区
、 工具条操作区
,如下图
我们按照这种分层进行代码编写,在 renderer/container/resume
文件夹下新增三个文件夹,每个文件夹都追加一个入口文件 index.tsx 和 index.less 文件
// app/renderer/container/resume/ResumeAction/index.tsx | |
import React from 'react'; | |
import './index.less'; | |
function ResumeAction() { | |
return <div>我是简历头部操作区</div>; | |
} | |
export default ResumeAction; |
// app/renderer/container/resume/ResumeContent/index.tsx | |
import React from 'react'; | |
import './index.less'; | |
function ResumeContent() { | |
return <div>我是简历内容展示区</div>; | |
} | |
export default ResumeContent; |
// app/renderer/container/resume/ResumeToolbar/index.tsx | |
import React from 'react'; | |
import './index.less'; | |
function ResumeToolbar() { | |
return <div>我是工具条操作区</div>; | |
} | |
export default ResumeToolbar; |
此刻我们去修改简历模块的入口文件 index.tsx
// app/renderer/container/resume/index.tsx | |
import React from 'react'; | |
import './index.less'; | |
// 👇 将组件引入 | |
import ResumeAction from './ResumeAction'; | |
import ResumeContent from './ResumeContent'; | |
import ResumeToolbar from './ResumeToolbar'; | |
function Resume() { | |
return ( | |
<div styleName="container"> | |
<div styleName="header"> | |
<ResumeAction /> | |
</div> | |
<div styleName="content"> | |
<ResumeContent /> | |
</div> | |
<div styleName="toolbar"> | |
<ResumeToolbar /> | |
</div> | |
</div> | |
); | |
} | |
export default Resume; |
加上 CSS 定位和布局
.container { | |
height: 100vh; | |
width: 100vw; | |
box-sizing: border-box; | |
background-color: #27292c; | |
// color: #fff; | |
.header { | |
height: 60px; | |
width: 820px; | |
padding-top: 16px; | |
margin-left: 32px; | |
background-color: #fff;// 一会调整时需要修改 | |
} | |
.content { | |
margin-left: 32px; | |
width: 820px; | |
margin-top: 16px; | |
height: calc(100vh - 76px - 16px); | |
background-color: #fff; | |
} | |
.toolbar { | |
width: 280px; | |
position: absolute; | |
top: 120px; | |
left: 888px; | |
border-radius: 6px; | |
box-sizing: border-box; | |
background-color: #fff; | |
} | |
} |
看样子布局方面没什么问题了,接下来按小模块,进行代码实现
# ResumeAction 操作区
在功能上,该组件只需要实现 返回首页
与 导出PDF
功能,这边我们只需要知道点击之后,触发导出事件即可。我们来修改 ResumeAction 中的 index.tsx
// app/renderer/container/resume/ResumeAction/index.tsx | |
import React from 'react'; | |
import './index.less'; | |
import { useHistory } from 'react-router'; | |
import ROUTER from '@common/constants/router'; | |
import MyButton from '@common/components/MyButton'; | |
function ResumeAction() { | |
const history = useHistory(); | |
// 返回首页 | |
const onBack = () => history.push(ROUTER.root); | |
// 导出 PDF | |
const onExport = () => {}; | |
return ( | |
<div styleName="actions"> | |
<div styleName="back" onClick={onBack}>返回</div> | |
<MyButton size="middle" className="export-btn" onClick={onExport}>导出PDF</MyButton> | |
</div> | |
); | |
} | |
export default ResumeAction; |
加上我们的 less 样式,并修改 resume 下的 index.less (.header 的 background-color->#27292c) 最后我们将操作区美化为下面效果图
//ResumeAction 下 less 样式 | |
.actions { | |
box-sizing: border-box; | |
padding: 12px; | |
border-radius: 6px; | |
display: flex; | |
justify-content: space-between; | |
align-items: center; | |
// background-color: #ffffff; | |
.back { | |
color: rgba(0, 0, 0, 0.6); | |
font-size: 16px; | |
cursor: pointer; | |
} | |
:global { | |
.export-btn { | |
text-align: center; | |
background-color: #27292c; | |
color: #ffffff; | |
} | |
} | |
} |
# ResumeContent 简历内容展示区
由于我们的简历模版需要展示且可修改内容,为此,我们在 ResumeContent
下新增一个文件夹,取名为 UseTemplate
,寓意为使用的模版,此文件夹下存放着将来用于制作的简历模版。
在上一节中事先准备好了一份静态简历模版,模版存放于: renderer/container/templates
,它的目的仅用于展示,告知用户当前有哪些模版可以选择,主要职责用于预览,而非制作。为了支持模版进行制作,我们将 templates 下的文件拷贝一份,存放在 /ResumeContent/UseTemplate
下,此时的文件目录为:
接着我们去修改 ResumeContent 中的 index.tsx,将这份简历模版引入并展示
// app/renderer/container/resume/ResumeContent/index.tsx | |
import React from 'react'; | |
import './index.less'; | |
// 👇 引入简历模版 | |
import * as UseTemplateList from './UseTemplate'; | |
import MyScrollBox from '@common/components/MyScrollBox'; | |
function ResumeContent() { | |
const HEADER_ACTION_HEIGHT = 92; | |
const height = document.body.clientHeight; | |
return ( | |
<MyScrollBox maxHeight={height - HEADER_ACTION_HEIGHT}> | |
<UseTemplateList.TemplateOne /> | |
</MyScrollBox> | |
); | |
} | |
export default ResumeContent; |
刷新页面,看看此刻的效果图
# ResumeToolbar 工具条操作区
距离简历制作的入口页面,仅差最后的 Toolbar 工具条模块了,让我们来实现一下它。
还记得第八章节中,我们对简历数据进行了划分,那么工具条模块的划分与之一一对应。
我们进入 renderer/common/constants
文件夹下,新增一个 resume.ts 常量文件,在里面定义我们工具条模块的相关信息。
// app/renderer/common/constants/resume.ts | |
export const RESUME_TOOLBAR_MAPS = { | |
personal: 'personal', // 个人信息 | |
contact: 'contact', // 联系方式 | |
education: 'education', // 教育信息 | |
workPrefer: 'workPrefer', // 工作期望 | |
schoolExperience: 'schoolExperience', // 在校经历 | |
projectExperience: 'projectExperience', // 项目经验 | |
workExperience: 'workExperience', // 工作经历 | |
certificate: 'certificate', // 获奖证书 | |
evaluation: 'evaluation', // 个人评价 | |
skill: 'skill', // 技能清单 | |
test: 'test', // 测试用例 | |
}; | |
const RESUME_TOOLBAR_LIST: TSResume.SliderItem[] = [ | |
{ | |
key: RESUME_TOOLBAR_MAPS.personal, | |
name: '个人信息', | |
summary: '更好介绍自己,机会会更多', | |
}, | |
{ | |
key: RESUME_TOOLBAR_MAPS.education, | |
name: '教育信息', | |
summary: '介绍你的学校和专业信息', | |
}, | |
{ | |
key: RESUME_TOOLBAR_MAPS.contact, | |
name: '联系方式', | |
summary: '少侠,请留下你的联系方式', | |
}, | |
{ | |
key: RESUME_TOOLBAR_MAPS.workPrefer, | |
name: '工作期望', | |
summary: '聊聊你所期望的宜人办公城市', | |
}, | |
{ | |
key: RESUME_TOOLBAR_MAPS.schoolExperience, | |
name: '在校经历', | |
summary: '展示在校任职成果和人际关系', | |
}, | |
{ | |
key: RESUME_TOOLBAR_MAPS.projectExperience, | |
name: '项目经验', | |
summary: '展示研究过什么优秀项目和成果', | |
}, | |
{ | |
key: RESUME_TOOLBAR_MAPS.workExperience, | |
name: '工作经历', | |
summary: '申请岗位的相关经验和能力', | |
}, | |
{ | |
key: RESUME_TOOLBAR_MAPS.certificate, | |
name: '获奖证书', | |
summary: '得过什么奖项值得炫耀', | |
}, | |
{ | |
key: RESUME_TOOLBAR_MAPS.evaluation, | |
name: '个人评价', | |
summary: '低调夸一夸自己有什么亮点', | |
}, | |
{ | |
key: RESUME_TOOLBAR_MAPS.skill, | |
name: '技能清单', | |
summary: '展示具备的技能,突出你的能力', | |
}, | |
{ | |
key: RESUME_TOOLBAR_MAPS.test, | |
name: '测试用例', | |
summary: '测试用例,一键覆盖', | |
}, | |
]; |
在 ResumeToolbar 中,我们修改 index.tsx,将工具条模块常量引入,遍历展示
/** | |
* @description 编辑简历 - 工具条模块 | |
*/ | |
import React from 'react'; | |
import './index.less'; | |
import MyScrollBox from '@common/components/MyScrollBox'; | |
import RESUME_TOOLBAR_LIST from '@common/constants/resume'; | |
function ResumeToolbar() { | |
const height = document.body.clientHeight; | |
return ( | |
<div styleName="slider"> | |
<MyScrollBox maxHeight={height - 180}> | |
<div styleName="module"> | |
<div styleName="title"> | |
<span styleName="line" /> | |
全部模块 | |
</div> | |
<div styleName="content"> | |
{RESUME_TOOLBAR_LIST.map((toolbar: TSResume.SliderItem) => { | |
return ( | |
<div styleName="box" key={toolbar.key}> | |
<div styleName="info"> | |
<i styleName="icon" /> | |
<div styleName="text"> | |
<div styleName="name">{toolbar.name}</div> | |
<div styleName="summary">{toolbar.summary}</div> | |
</div> | |
</div> | |
</div> | |
); | |
})} | |
</div> | |
</div> | |
</MyScrollBox> | |
</div> | |
); | |
} | |
export default ResumeToolbar; |
刷新一下页面,我们看看最终效果
静态版本代码