vue整合editor.md解决多个editor.md同时共存问题v-model数据绑定
点击下载demo
定义editor.md为vue组件
安装 scriptjs
cnpm install --save scriptjs
在components文件夹下面创建一个组件
<template>
<div class="markdown-editor-box">
<link rel="stylesheet" href="/editormd/css/editormd.min.css">
<div :id="editorId"></div>
</div>
</template>
<script>
function uuid () {
let s = []
let hexDigits = '0123456789abcdef'
for (let i = 0; i < 36; i++) {
s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1)
}
s[14] = '4'
s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1)
s[8] = s[13] = s[18] = s[23] = '-'
return s.join('')
}
export default {
model: {
prop: 'content',
event: 'onChangeContent'
},
props: {
show: {
type: Boolean,
default: false
},
tag: {
type: String,
default: uuid()
},
editorId: {
type: String,
default: uuid()
},
onchange: {
type: Function
},
config: {
type: Object
},
content: {
type: String,
default: ''
},
delay: {
type: Number,
default: 0
}
},
data: function () {
return {
editor: null,
defaultConfig: {
width: '100%',
height: 680,
path: '/editormd/lib/',
markdown: '',
codeFold: true,
saveHTMLToTextarea: true,
searchReplace: true,
emoji: true,
taskList: true,
tocm: true,
tex: true,
flowChart: true,
sequenceDiagram: true,
imageUpload: true,
imageFormats: ['jpg', 'jpeg', 'gif', 'png', 'bmp', 'webp'],
imageUploadURL: './php/upload.php',
htmlDecode: 'style,script,iframe',
onload: function () {
this.watch()
},
onchange: function () {
if (this.onContentChange && typeof this.onContentChange === 'function') {
this.onContentChange(this)
}
}
}
}
},
methods: {
getConfig () {
return {
...this.defaultConfig, ...this.config }
},
getEditor () {
return this.editor
},
watch () {
return this.editor.watch()
},
unwatch () {
return this.editor.unwatch()
},
previewing () {
return this.editor.previewing()
},
getHTML () {
return this.editor.getHTML()
},
getMarkdown () {
return this.editor.getMarkdown()
},
setMarkdown (markdown) {
return this.editor.setMarkdown(markdown)
},
onContentChange (editor) {
let res = {
markdown: editor.getMarkdown(),
tag: this.tag,
editorId: this.editorId,
editor: editor,
vm: this
}
if (this.onchange) {
this.onchange(res)
}
this.$emit('onChangeContent', res.markdown)
},
initEditor (markdown) {
let config = this.getConfig()
if (markdown) {
config.markdown = markdown
}
window.editormd.emoji = {
path: '/editormd/plugins/emoji-dialog/emoji/',
ext: '.png'
}
window.editormd.twemoji = {
path: 'http://twemoji.maxcdn.com/72x72/',
ext: '.png'
}
config.onload = function () {
setTimeout(() => {
if (this._vm && this._vm.content) {
this.setMarkdown(this._vm.content)
}
}, this.delay)
this.watch()
}
this.$nextTick(() => {
this.editor = window.editormd(this.editorId, config)
this.editor.onContentChange = this.onContentChange
this.editor._vm = this
})
}
},
mounted () {
this.initEditor(this.content)
}
}
</script>
在vuex store全局中加载所需js等文件
目录截图

安装 scriptjs
actions.js文件
import scriptjs from 'scriptjs'
export function testAction1 (content, data) {
}
export function testAction2 ({
commit, dispatch, getters, rootGetters, rootState, state }, data) {
}
const fetchScript = function (url) {
return new Promise((resolve) => {
scriptjs(url, () => {
resolve()
})
})
}
export function loadJs ({
commit, dispatch, getters, rootGetters, rootState, state }, data) {
return new Promise((resolve, reject) => {
if (!state.loading.loadJs && window.editormd) {
resolve()
return
}
if (state.loading.loadJs) {
let num = 0
let index = setInterval(() => {
try {
if (!state.loading.loadJs && window.editormd) {
try {
resolve()
} catch (e) {
}
clearInterval(index)
}
} catch (e) {
}
num++
if (num > 100) {
try {
reject('超时退出')
} catch (e) {
}
clearInterval(index)
}
}, 200)
return
}
commit('setLoadinLoadJS', true);
(async () => {
await fetchScript('/jquery.min.js')
await fetchScript('/editormd/lib/marked.min.js')
await fetchScript('/editormd/lib/prettify.min.js')
await fetchScript('/editormd/lib/raphael.min.js')
await fetchScript('/editormd/lib/underscore.min.js')
await fetchScript('/editormd/lib/sequence-diagram.min.js')
await fetchScript('/editormd/lib/flowchart.min.js')
await fetchScript('/editormd/lib/jquery.flowchart.min.js')
await fetchScript('/editormd/editormd.min.js')
resolve()
commit('setLoadinLoadJS', false)
})()
})
}
vuex的mutations文件
export function setLoadinLoadJS (state, status) {
state.loading.loadJs = status
}
vuex的state文件
export default function () {
return {
loading: {
loadJs: false
},
editors: {
}
}
}
最后使用例子
<template>
<div class="row" v-if="isShow">
<div class="col-12">
<markdown editor-id="article_dec" :onchange="onchangeEditor" tag="article_dec"
v-model="article.desc"></markdown>
</div>
<div class="col-12">
<markdown editor-id="article_content" :onchange="onchangeEditor" tag="article_content"
v-model="article.content"></markdown>
</div>
</div>
</template>
<script>
import Markdown from './components/editormd.vue'
export default {
name: 'x',
components: {
Markdown },
data () {
return {
isShow: false,
article: {
desc: '',
content: ''
}
}
},
created () {
this.$store.dispatch('editor/loadJs').then(e => {
this.isShow = true
})
},
methods: {
onchangeEditor (e) {
console.log(e)
}
}
}
</script>
<style scoped>
</style>