上传图片 按钮及事件
<input ref="image" style="display:none;" type="file" accept="image/*" @change="uploadImage">
initEditor(){
this.editor = new Editor({
el: document.getElementById(this.id),
...this.editorOptions
})
if(this.value){
this.editor.setValue(this.value)
}
this.editor.on('change', ()=>{
this.$emit('input', this.editor.getValue())
})
//获取菜单栏
const toolbar = this.editor.getUI().getToolbar()
//图片上传按钮及事件
const imageDom = this.$refs.image
this.editor.eventManager.addEventType('uploadEvent')
this.editor.eventManager.listen('uploadEvent', ()=>{
imageDom.click()
})
toolbar.insertItem(15, {
type: 'button',
options: {
className: 'el-icon-picture',
event: 'uploadEvent',
tooltip: '插入图片',
text:'',
style: 'font-size:14px;color:#000;background:none'
}
})
}
//图片上传
uploadImage(e){
const target = e.target
const file = target.files[0]
const formdata = new FormData()
formdata.append('file', file)
uploadImageFile(formdata).then((res)=>{ //调接口
if(res.success){
const imgUrl = res.url
this.addImgToMd(imgUrl, filename)
}
})
target.value = '' //清除数据
},
//添加图片到编辑器中
addImgToMd(data, imgname){
const editor = this.editor.getCodeMirror()
const editorHtml = this.editor.getCurrentModeEditor()
const isMarkdownMode = this.editor.isMarkdownMode()
if(isMarkdownMode){
editor.replaceSelection(`![${imgname}](${data})`)
} else {
const range = editorHtml.getRange()
const img = document.createElement('img')
img.src = `${data}`
img.alt = `${imgname}`
range.insertNode(img)
}
}
导入文件按钮及事件
<input ref="file" style="display:none;" type="file" accept=".md" @change="uploadFile">
//导入文件按钮及事件
const fileDom = this.$refs.file
this.editor.eventManager.addEventType('uploadFileEvent')
this.editor.eventManager.listen('uploadFileEvent', ()=>{
fileDom.click()
})
toolbar.insertItem(23, {
type: 'button',
options: {
className: 'el-icon-upload',
event: 'uploadFileEvent',
tooltip: '导入md文件',
text:'',
style: 'font-size:14px;color:#000;background:none'
}
})
uploadFile(e){
const target = e.target
const file = target.files[0]
const reader = new FileReader()
const that = this
reader.onload = function(evt) {
that.setValue(evt.target.result) //向编辑器传值
}
reader.readAsText(file)
}
导出文件按钮及事件
//导出文件按钮及事件
this.editor.eventManager.addEventType('exportFileEvent')
this.editor.eventManager.listen('exportFileEvent', ()=>{
const md = this.editor.getValue()
//获取当前日期
const date = new Date()
const year = date.getFullYear()
const month = date.getMonth() + 1
const day = date.getDate()
const today = year + '-' + month + '-' + day
this.exportFile(md, today + '.md') //不加后缀,默认为txt文件
})
toolbar.insertItem(24, {
type: 'button',
options: {
className: 'el-icon-download',
event: 'exportFileEvent',
tooltip: '导出md文件',
text:'',
style: 'font-size:14px;color:#000;background:none'
}
})
//导出文件
exportFile(content, filename){
const linkNode = document.createElement('a')
linkNode.download = filename
linkNode.style.display = 'none'
// 利用Blob对象将字符内容转变成二进制数据
var blob = new Blob([content])
linkNode.href = URL.createObjectURL(blob)
// 触发点击
document.body.appendChild(linkNode)
linkNode.click()
// 移除
document.body.removeChild(linkNode)
}
<template>
<div>
<div :id="id" />
<input ref="image" style="display:none;" type="file" accept="image/*" @change="uploadImage">
<input ref="file" style="display:none;" type="file" accept=".md" @change="uploadFile">
div>
template>
<script>
// deps for editor
import 'codemirror/lib/codemirror.css' // codemirror
import 'tui-editor/dist/tui-editor.css' // editor ui
import 'tui-editor/dist/tui-editor-contents.css' // editor content
import Editor from 'tui-editor'
import defaultOptions from '@/components/MarkdownEditor/default-options'
// 自定义图片上传地址
import { uploadDescriptionFile } from '@/api/document'
export default {
name: 'MarddownEditor',
props: {
value: {
type: String,
default: ''
},
id: {
type: String,
required: false,
default() {
return 'markdown-editor-' + +new Date() + ((Math.random() * 1000).toFixed(0) + '')
}
},
options: {
type: Object,
default() {
return defaultOptions
}
},
mode: {
type: String,
default: 'markdown'
},
height: {
type: String,
required: false,
default: '300px'
},
language: {
type: String,
required: false,
default: 'zh_CN' // https://github.com/nhnent/tui.editor/tree/master/src/js/langs
}
},
data() {
return {
editor: null
}
},
computed: {
editorOptions() {
const options = Object.assign({}, defaultOptions, this.options)
options.initialEditType = this.mode
options.height = this.height
options.language = this.language
return options
}
},
watch: {
value(newValue, preValue) {
if (newValue !== preValue && newValue !== this.editor.getValue()) {
this.editor.setValue(newValue)
}
},
language(val) {
this.destroyEditor()
this.initEditor()
},
height(newValue) {
this.editor.height(newValue)
},
mode(newValue) {
this.editor.changeMode(newValue)
}
},
mounted() {
this.initEditor()
},
destroyed() {
this.destroyEditor()
},
methods: {
initEditor() {
this.editor = new Editor({
el: document.getElementById(this.id),
...this.editorOptions
})
if (this.value) {
this.editor.setValue(this.value)
}
this.editor.on('change', () => {
this.$emit('input', this.editor.getValue())
})
/*
* 添加自定义按钮
* */
// 获取编辑器上的功能条,即菜单栏
const toolbar = this.editor.getUI().getToolbar()
const imageDom = this.$refs.image
// 添加图片上传事件
this.editor.eventManager.addEventType('uploadEvent')
this.editor.eventManager.listen('uploadEvent', () => {
imageDom.click()
})
// 添加自定义按钮
toolbar.insertItem(15, {
type: 'button',
options: {
className: 'el-icon-picture',
event: 'uploadEvent',
tooltip: '插入图片',
text: '',
style: 'font-size:14px;color:#000;background:none;'
}
})
// 导入文件按钮
const fileDom = this.$refs.file
this.editor.eventManager.addEventType('importfileEvent')
this.editor.eventManager.listen('importfileEvent', () => {
fileDom.click()
})
toolbar.insertItem(23, {
type: 'button',
options: {
className: 'el-icon-upload2',
event: 'importfileEvent',
tooltip: '导入md文件',
text: '',
style: 'font-size:14px;color:#000;background:none;'
}
})
// 添加保存文档事件
// this.editor.eventManager.addEventType('saveEvent')
// this.editor.eventManager.listen('saveEvent', () => {
// this.$emit('save')
// })
// toolbar.insertItem(22, {
// type: 'button',
// options: {
// className: 'el-icon-s-claim',
// event: 'saveEvent',
// tooltip: '保存文档',
// text: '',
// style: 'font-size:14px;color:#000;background:none;'
// }
// })
// 导出md文件按钮
this.editor.eventManager.addEventType('exportEvent')
this.editor.eventManager.listen('exportEvent', () => {
const md = this.editor.getValue()
// 获取当前日期
const date = new Date()
const year = date.getFullYear()
const month = date.getMonth() + 1
const day = date.getDate()
const today = year + '-' + month + '-' + day
this.downloadF(md, today + '.md') // 不加后缀,默认是txt格式
})
toolbar.insertItem(24, {
type: 'button',
options: {
className: 'el-icon-download',
event: 'exportEvent',
tooltip: '导出md文件',
text: '',
style: 'font-size:14px;color:#000;background:none;'
}
})
},
downloadF(content, filename) {
const linkNode = document.createElement('a')
linkNode.download = filename
linkNode.style.display = 'none'
// 利用Blob对象将字符内容转变成二进制数据
const blob = new Blob([content])
linkNode.href = URL.createObjectURL(blob)
// 点击
document.body.appendChild(linkNode)
linkNode.click()
// 移除
document.body.removeChild(linkNode)
},
destroyEditor() {
if (!this.editor) return
this.editor.off('change')
this.editor.remove()
},
setValue(value) {
this.editor.setValue(value)
},
getValue() {
return this.editor.getValue()
},
setHtml(value) {
this.editor.setHtml(value)
},
getHtml() {
return this.editor.getHtml()
},
/*
* 自定义图片上传
* */
uploadImage(e) {
const target = e.target
const file = target.files[0]
const formdata = new FormData()
formdata.append('file', file)
uploadDescriptionFile(formdata).then((res) => {
if (res.success) {
const imgUrl = res.url
this.addImgToMd(imgUrl, file.name)
}
}).catch(error => {
this.$message.error(error.msg)
})
target.value = '' // 清除数据
},
// 添加图片到markdown
addImgToMd(data, imgname) {
const editor = this.editor.getCodeMirror()
const editorHtml = this.editor.getCurrentModeEditor()
const isMarkdownMode = this.editor.isMarkdownMode()
if (isMarkdownMode) {
editor.replaceSelection(`![${imgname}](${data})`)
} else {
const range = editorHtml.getRange()
const img = document.createElement('img')
img.src = `${data}`
img.alt = `${imgname}`
range.insertNode(img)
}
},
// 导入md文件
uploadFile(e) {
const target = e.target
const file = target.files[0]
var reader = new FileReader()
const that = this
reader.onload = function(evt) {
that.setValue(evt.target.result)// 向编辑器传值
}
reader.readAsText(file)
}
}
}
script>
<style lang="scss">
.tui-tooltip{
z-index:9999
}
style>