vue.js+muse-ui制作在线简历编辑
实现一个在线个人简历编辑器,实现在线编辑,生成简历图片,运用到技术:1.vue.js2.webpack3.muse-ui(https://museui.github.io)4.html2canvas.js(用来将html生成图片);已经开发好的项目目录如下:然后是我的简历整体效果(利用组件的思想,这里每个模块就是一个组件,有些模块一样,可以进一步改善,这里我暂时没有)一. 搭建vue项目
实现一个在线个人简历编辑器,实现在线编辑,生成简历图片,运用到技术:
1.vue.js
2.webpack
3.muse-ui(https://museui.github.io)
4.html2canvas.js(用来将html生成图片);
已经开发好的项目目录如下:
然后是我的简历整体效果
(利用组件的思想,这里每个模块就是一个组件,有些模块一样,可以进一步改善,这里我暂时没有)
一. 搭建vue项目
首先用vue-cli搭建我们的项目,没用过的同学可以去看我之前的博客,有专门介绍
二. 引入muse-ui
在项目目录下,安装muse-ui
nam install muse-ui --save -dev
在main.js中引入
import MuseUI from 'muse-ui';
import '../static/css/muse-ui.css';
import '../static/css/theme-carbon.css' // 使用 carbon 主题(可更改)
Vue.use(MuseUI)
如果要用到muse-ui自带的图标的话,在index.html引入两个文件:
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700,400italic">
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
这样就可以在muse-ui官网上复制例子玩了,网上很多muse-ui教程讲得比较复杂,这里我用最简单的方法实现,这里不做演示,有兴趣的同学可以去试试。
三. 头像模块HeaderImg.vue
<template>
<div class="headerImg">
<img :src="pictureUrl" alt="" />
<input type="file" class="file-button" @change="onFileChange" />
</div>
</template>
<style></style>
<script>
export default{
data(){
return {
images:[],
pictureUrl:'../../static/img/headerImg.jpg'
}
},
methods:{
test () {
var vm = this
console.log(vm.message)
},
onFileChange (e) {
var files = e.target.files || e.dataTransfer.files
if (!files.length) return
var _this = this
var reader = null
reader = new window.FileReader()
reader.readAsDataURL(files[0])
reader.onload = function (e) {
_this.pictureUrl = e.target.result
}
},
},
}
</script>
四.个人信息模块(写在Home.vue)
<div class="baseInfo">
<mu-text-field hintText="输入年龄" type="type" icon="face" fullWidth :underlineShow="false" />
<mu-text-field hintText="输入住址" type="type" icon="place" fullWidth :underlineShow="false"/>
<mu-text-field hintText="输入电话号码" type="type" icon="phone" fullWidth :underlineShow="false"/>
<mu-text-field hintText="输入邮箱" type="type" icon="mail" fullWidth :underlineShow="false"/>
</div>
五. 技能特点模块
<template>
<div class="skills">
<div class="title">
<span class="">技能特点</span>
<a href="javascrpt:;" class="add addBtn" @click="openSkills">
<mu-icon value="add" color="#fff" />
</a>
</div>
<div>
<mu-dialog :open="skillsDialog" title="技能特点" @close="closeSkills">
<mu-text-field label="掌握的技术" labelFloat fullWidth v-model="skill.name"/>
<mu-row gutter>
<mu-col width="60" table="60" desktop="80">
<mu-slider v-model="skill.value" class="demo-slider" :min=0 :max=100 :step="5" />
</mu-col>
<mu-col width="60" table="60" desktop="20">
<span>{{skill.value}}</span>
<span>/</span>
<span>100</span>
</mu-col>
</mu-row>
<mu-flat-button slot="actions" @click="closeSkills" primary label="取消"/>
<mu-flat-button slot="actions" primary label="确定" @click="skillData" />
</mu-dialog>
</div>
<div class="skill-item">
<div v-if="skillEmpty" class="empty">请先添加技能特点</div>
<div v-for="(item,index) in skills" class="list" v-else>
<p>
<span>{{item.name}}</span>
<a href="javascript:;" class="delete" @click="deleteSkill(index)">
<mu-icon value="delete" />
</a>
</p>
<mu-linear-progress mode="determinate" :value="item.value"/>
</div>
</div>
</div>
</template>
<style></style>
<script>
export default {
data () {
return {
value: 20,
skillsDialog:false,
skill:{
name:"",
value:0
},
skills:[],
skillEmpty:true,
}
},
methods: {
openSkills () {
this.skillsDialog = true
},
closeSkills () {
this.skillsDialog = false
},
skillData(){
this.skills.push(this.skill);
this.skill={
name:"",
value:0
};
this.skillsDialog = false;
this.skillEmpty = false;
console.log(this.skills)
},
deleteSkill(index){
this.skills.splice(index,1);
if(this.interests==0){
this.interestEmpty = true;
}
}
}
}
</script>
六. 教育背景模块(Education.vue)
<template>
<div class="education">
<div class="title">
<mu-icon value="school" color="#1d3653" />
<span>教育背景</span>
</div>
<mu-float-button icon="add" mini class="demo-float-button educationBtn" @click="openEducation" />
<mu-dialog :open="educationDialog" title="教育背景" @close="closeEducation">
<mu-row gutter>
<mu-col width="50" table="30" desktop="20">
<mu-date-picker mode="landscape" hintText="开始时间" fullWidth v-model="edu.startTime" />
</mu-col>
<mu-col width="50" table="30" desktop="20">
<mu-date-picker mode="landscape" hintText="结束时间" fullWidth v-model="edu.endTime" />
</mu-col>
<mu-col width="50" table="30" desktop="35">
<mu-text-field hintText="毕业学校" fullWidth v-model="edu.school" />
</mu-col>
<mu-col width="50" table="30" desktop="25">
<mu-text-field hintText="专业技能" fullWidth v-model="edu.professional" />
</mu-col>
</mu-row>
<mu-row gutter>
<mu-col width="100" table="100" desktop="100">
<mu-text-field hintText="输入教育背景详情" multiLine :rows="1" :rowsMax="5" fullWidth v-model="edu.content" />
</mu-col>
</mu-row>
<mu-flat-button slot="actions" @click="closeEducation" primary label="关闭"/>
<mu-flat-button slot="actions" primary label="确定" @click="eduData" />
</mu-dialog>
<div class="education-content lists">
<div v-if="empty" class="empty">请添加教育背景</div>
<div v-for="(item,index) in edus" class="list" v-else>
<mu-row gutter>
<mu-col width="50" table="30" desktop="30">
<span class="title-font">{{item.startTime}}</span>
<span class="title-font">--</span>
<span class="title-font">{{item.endTime}}</span>
</mu-col>
<mu-col width="50" table="30" desktop="30">
<span class="title-font">{{item.school}}</span>
</mu-col>
<mu-col width="50" table="30" desktop="30">
<span class="title-font">{{item.professional}}</span>
</mu-col>
<mu-col width="50" table="5" desktop="10">
<a href="javascript:;" class="deleteBtn" @click="deleteData(index)">
<mu-icon value="delete" color="#fff" />
</a>
</mu-col>
</mu-row>
<mu-row gutter>
<mu-col width="100" table="100" desktop="100">
<span class="content-font">{{item.content}}</span>
</mu-col>
</mu-row>
</div>
</div>
</div>
</template>
<style></style>
<script>
export default{
data(){
return {
educationDialog:false,
empty:true,
edu:{
startTime:"",
endTime:"",
school:"",
professional:"",
content:"",
},
edus:[],
}
},
methods: {
openEducation () {
this.educationDialog = true
},
closeEducation () {
this.educationDialog = false
},
eduData(){
this.edus.push(this.edu);
this.edu = {
startTime:"",
endTime:"",
school:"",
professional:"",
content:"",
};
this.educationDialog = false;
this.empty = false;
},
deleteData(index){
this.edus.splice(index,1);
if(this.edus.length==0){
this.empty = true;
}
},
},
}
</script>
其他的模块功能实现都差不多,有兴趣的同学可以自己去试试,最后我们再生成简历,这里要借助html2canvas,不清楚的可以百度查查该插件的使用方法
在Home.vue中引入
import Html2canvas from '../../static/js/html2canvas';
<script>
import HeaderImg from './HeaderImg';
import Skills from './Skills';
import Interest from './Interest';
import Education from './Education';
import Work from './Work';
import Award from './Award';
import Assessment from './Assessment';
import Html2canvas from '../../static/js/html2canvas';
export default{
data(){
return{
url:"",
resumeImg:"../../static/img/headerImg.jpg",
readResume:false
}
},
methods:{
createImg(){
var canvas = document.querySelector("canvas");
var ctx = canvas.getContext("2d");
var _this = this;
Html2canvas(document.querySelector("#app"), {
onrendered: function(canvas){
var img = canvas.toDataURL();
_this.url = img;
_this.resumeImg = img;
_this.readResume = true;
},
});
},
closeResume(){
this.readResume = false;
},
},
components:{
Skills,
Interest,
Education,
Work,
Award,
Assessment,
HeaderImg
}
}
</script>
点击下载简历,会下载该简历图片,
这里下载的图片可能有点模糊,具体原因我也没去深究,也是边学边做,有清楚的同学可以交流交流。
GitHub地址:https://github.com/antkonw/vue_resume 记得关注,给星哈
好了,在线简历就这样做好了,等我搭建好服务器,可以放在线上让大家玩玩。
更多推荐
所有评论(0)