Vue中好用的markdown编辑器--mavonEditor
一、介绍Markdown是一种可以使用普通文本编辑器编写的标记语言,通过简单的标记语法,它可以使普通文本内容具有一定的格式。mavonEditor是国人开源的一款比较好用的markdown编辑器,GitHub地址:https://github.com/hinesboy/mavonEditor二、安装npm install mavon-editor --save如果下载不了或安装失...
一、介绍
Markdown是一种可以使用普通文本编辑器编写的标记语言,通过简单的标记语法,它可以使普通文本内容具有一定的格式。mavonEditor是国人开源的一款比较好用的markdown编辑器,GitHub地址:https://github.com/hinesboy/mavonEditor
二、安装
npm install mavon-editor --save
如果下载不了或安装失败可以(当然你得装了cnpm)
cnpm install mavon-editor --save
如果没装cnpm,也可以
npm install mavon-editor --save --registry=https://registry.npm.taobao.org
这是国人开发的,一般npm即可
三、使用
main.js
:
// 全局注册
// import with ES6
import Vue from 'vue'
import mavonEditor from 'mavon-editor'
import 'mavon-editor/dist/css/index.css'
// use
Vue.use(mavonEditor)
new Vue({
'el': '#main',
data() {
return { value: '' }
}
})
index.vue:
<template>
<div class="app-container">
<el-form :label-position="'left'" :model="markdownForm" :rules="rules" label-width="60px" >
<el-form-item label="标 题" prop="title">
<el-input v-model="markdownForm.title"></el-input>
</el-form-item>
</el-form>
<mavon-editor ref="md" @save="save" @imgAdd="imgAdd" @imgDel="imgDel" v-model="markdownForm.contentMarkdown" :codeStyle="markdown.codeStyle" :toolbars="markdown.toolbars" />
<br>
<el-row>
<el-col :span="2">
<el-button @click="goback">返 回</el-button>
</el-col>
<el-col :span="2" :offset="20">
<el-button type="primary" style="float: right;" @click="save">保 存</el-button>
</el-col>
</el-row>
</div>
</template>
<script>
import {getMarkdownArticle,saveMarkdownArticle} from '@/api/markdownArticle'
import {uploadImg} from '@/api/markdownArticleImg'
export default {
data() {
return {
markdown:{
codeStyle:'atom-one-dark',
toolbars:{
bold: true, // 粗体
italic: true, // 斜体
header: true, // 标题
underline: true, // 下划线
strikethrough: true, // 中划线
mark: true, // 标记
superscript: true, // 上角标
subscript: true, // 下角标
quote: true, // 引用
ol: true, // 有序列表
ul: true, // 无序列表
link: true, // 链接
imagelink: true, // 图片链接
code: true, // code
table: true, // 表格
fullscreen: true, // 全屏编辑
readmodel: true, // 沉浸式阅读
htmlcode: true, // 展示html源码
help: true, // 帮助
/* 1.3.5 */
undo: true, // 上一步
redo: true, // 下一步
trash: true, // 清空
save: true, // 保存(触发events中的save事件)
/* 1.4.2 */
navigation: true, // 导航目录
/* 2.1.8 */
alignleft: true, // 左对齐
aligncenter: true, // 居中
alignright: true, // 右对齐
/* 2.2.1 */
subfield: true, // 单双栏模式
preview: false, // 预览
}
},
markdownForm : {
articleId:null,
title:"",
contentMarkdown:'',
contentHtml:null,
type:0
},
rules: {
title: [
{ required: true, message: '请输入标题', trigger: 'blur' },
{ min: 1, max: 80, message: '长度在1到80个字符', trigger: 'blur' }
]
},
lastSaveTime:null,
timer:null
}
},
created(){
this.getArticle()
},
mounted() {
this.timer = setInterval(this.intervalSave, 2*60*1000);
},
beforeDestroy() {
clearInterval(this.timer);
},
methods: {
getArticle(){ //获取文章内容
let id=this.$route.query.a
if(id==null){
this.markdownForm.contentMarkdown=''
}else{
getMarkdownArticle(id).then(r => {
this.markdownForm.contentMarkdown=r.data.contentMarkdown==null?'':r.data.contentMarkdown
this.markdownForm.articleId=r.data.articleId
this.markdownForm.title=r.data.title
this.markdownForm.type=r.data.type
}).catch(e => {
console.log(e)
})
}
},
save(){ //保存文章内容
saveMarkdownArticle(this.markdownForm).then(r => {
this.$message.success("保存成功")
this.markdownForm.articleId=r.data.articleId
this.lastSaveTime=new Date()
}).catch(e => {
console.log(e)
})
},
intervalSave(){ //自动保存
let now = new Date()
if(now-this.lastSaveTime>=2*60*1000){
saveMarkdownArticle(this.markdownForm).then(r => {
this.$message.success("自动保存成功")
this.lastSaveTime=new Date()
}).catch(e => {
console.log(e)
})
}
},
imgAdd(pos, file){ //添加图片,pos为位置
let markdownImg = {},$vm=this.$refs.md
markdownImg.base64Data=file.miniurl //获取图片base64内容
markdownImg.type=file.type
uploadImg(markdownImg).then(r => {
console.log(r)
$vm.$img2Url(pos,process.env.VUE_APP_BASE_API+'/img/'+r.data)
}).catch(e => {
console.log(e)
})
},
imgDel(pos,url){ //删除图片,并不是修改就会触发,仅支持工具栏操作
console.log(pos)
console.log(url)
}
}
}
</script>
<style lang="scss">
.v-note-panel.shadow{
min-height: 440px; //设置编辑框最小高度
}
</style>
api/markdownArticle:
import request from '@/utils/request'
export function getMarkdownArticles() {
return request({
url: '/edu/markdown/articles',
method: 'get'
})
}
export function getMarkdownArticle(id) {
return request({
url: '/edu/markdown/article/'+id,
method: 'get'
})
}
export function saveMarkdownArticle(data) {
return request({
url: '/edu/markdown/article',
method: 'post',
data
})
}
/**
* 发布/取消发布
* @param data
*/
export function updateStatus(data) {
return request({
url: '/edu/markdown/article/status',
method: 'post',
data
})
}
/**
* 删除
* @param data
*/
export function del(data) {
return request({
url: '/edu/markdown/article',
method: 'delete',
data
})
}
api/markdownArticleImg
import request from '@/utils/request'
export function uploadImg(data) {
return request({
url: '/edu/markdown/img',
method: 'put',
data
})
}
utils/request仅是对axios的简单封装,没有特殊处理,参照vue-element-admin里request的写法
四、详细
props
name 名称 | type 类型 | default 默认值 | describe 描述 |
---|---|---|---|
value | String | 初始值 | |
language | String | zh-CN | 语言选择,暂支持 zh-CN: 中文简体 , en: 英文 , fr: 法语, pt-BR: 葡萄牙语, ru: 俄语, de: 德语, ja: 日语 |
fontSize | String | 15px | 编辑区域文字大小 |
scrollStyle | Boolean | true | 开启滚动条样式(暂时仅支持chrome) |
boxShadow | Boolean | true | 开启边框阴影 |
subfield | Boolean | true | true: 双栏(编辑预览同屏), false: 单栏(编辑预览分屏) |
defaultOpen | String | edit: 默认展示编辑区域 , preview: 默认展示预览区域 , 其他 = edit | |
placeholder | String | 开始编辑... | 输入框为空时默认提示文本 |
editable | Boolean | true | 是否允许编辑 |
codeStyle | String | code-github | markdown样式: 默认github, 可选配色方案 |
toolbarsFlag | Boolean | true | 工具栏是否显示 |
navigation | Boolean | false | 默认展示目录 |
shortCut | Boolean | true | 是否启用快捷键 |
autofocus | Boolean | true | 自动聚焦到文本框 |
ishljs | Boolean | true | 代码高亮 |
imageFilter | function | null | 图片过滤函数,参数为一个File Object ,要求返回一个Boolean , true 表示文件合法,false 表示文件不合法 |
imageClick | function | null | 图片点击事件,默认为预览,可覆盖 |
tabSize | Number | \t | tab转化为几个空格,默认为\t |
toolbars | Object | 如下例 | 工具栏 |
events 事件绑定
name 方法名 | params 参数 | describe 描述 |
---|---|---|
change | String: value , String: render | 编辑区发生变化的回调事件(render: value 经过markdown解析后的结果) |
save | String: value , String: render | ctrl + s 的回调事件(保存按键,同样触发该回调) |
fullScreen | Boolean: status , String: value | 切换全屏编辑的回调事件(boolean: 全屏开启状态) |
readModel | Boolean: status , String: value | 切换沉浸式阅读的回调事件(boolean: 阅读开启状态) |
htmlCode | Boolean: status , String: value | 查看html源码的回调事件(boolean: 源码开启状态) |
subfieldToggle | Boolean: status , String: value | 切换单双栏编辑的回调事件(boolean: 双栏开启状态) |
previewToggle | Boolean: status , String: value | 切换预览编辑的回调事件(boolean: 预览开启状态) |
helpToggle | Boolean: status , String: value | 查看帮助的回调事件(boolean: 帮助开启状态) |
navigationToggle | Boolean: status , String: value | 切换导航目录的回调事件(boolean: 导航开启状态) |
imgAdd | String: filename, File: imgfile | 图片文件添加回调事件(filename: 写在md中的文件名, File: File Object) |
imgDel | String: filename | 图片文件删除回调事件(filename: 写在md中的文件名) |
代码高亮
如不需要hightlight代码高亮显示,你应该设置ishljs为false,默认开启所以不需要设置,主要是选择代码样式,即codeStyle属性,可以先到方案对应样式里找到你想要的样式,再到可选配色方案里找具体的对应名称
图片上传
<template>
<mavon-editor ref=md @imgAdd="$imgAdd" @imgDel="$imgDel"></mavon-editor>
</template>
exports default {
methods: {
// 绑定@imgAdd event
$imgAdd(pos, $file){
// 第一步.将图片上传到服务器.
var formdata = new FormData();
formdata.append('image', $file);
axios({
url: 'server url',
method: 'post',
data: formdata,
headers: { 'Content-Type': 'multipart/form-data' },
}).then((url) => {
// 第二步.将返回的url替换到文本原位置![...](0) -> ![...](url)
/**
* $vm 指为mavonEditor实例,可以通过如下两种方式获取
* 1. 通过引入对象获取: `import {mavonEditor} from ...` 等方式引入后,`$vm`为`mavonEditor`
* 2. 通过$refs获取: html声明ref : `<mavon-editor ref=md ></mavon-editor>,`$vm`为 `this.$refs.md`
*/
$vm.$img2Url(pos, url);
})
}
}
}
注
- 默认大小样式为 min-height: 300px , min-width: 300px 可自行覆盖
- 基础z-index: 1500
- 仅用作展示可以设置props: toolbarsFlag: false , subfield: false, defaultOpen: "preview"
这里也提到了,当我们仅需要展示的时候,可以设置 toolbarsFlag: false , subfield: false, defaultOpen: "preview",即
<mavon-editor :toolbarsFlag="false" :subfield="false" defaultOpen="preview" v-model="article.contentMarkdown" :codeStyle="markdown.codeStyle"/>
整理不易,感谢赞赏~~~~~
更多推荐
所有评论(0)