记录mavon-editor在Vue中的使用(编辑及预览功能)

161 阅读2分钟

1.安装mavon-editor

npm install mavon-editor --save

2.全局引入

import mavonEditor from 'mavon-editor'
import 'mavon-editor/dist/css/index.css'
Vue.use(mavonEditor)

3.页面使用编辑(完整代码)

<template>
  <div class="markdown">
    <mavon-editor :toolbars="toolbars" @imgAdd="handleEditorImgAdd" @imgDel="handleEditorImgDel" style="height:740px"
      v-model="value" @change="change" @save="save" ref=md  @navigationToggle="addUrl"/>
  </div>
</template>

<script>
import { uploadFileApi } from "@/api/kpi/index";
import { showMarkdownApi,editMarkdownApi } from "@/api/system/user";
export default {
  data () {
    return {
   	  //工具栏配置
      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: false, // code
        table: true, // 表格
        fullscreen: false, // 全屏编辑
        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: true, // 预览
      },
      html: undefined,
      value: ''
    };
  },
  mounted () {
    this.getMarkdown()
  },
  methods: {
    //监听markdown变化
    change (value, render) {
      this.html = render;
    },
    // 从后台获取之前保存的内容
    async getMarkdown(){
      const res = await showMarkdownApi({ format:'markdown' })
      this.value = res.data
    },
    // 点击保存将文档传到后台
    async save (value, render) {
      const res = await editMarkdownApi({
        html:render,
        markdown:value
      })
      this.$message.success('编辑成功')
    },
    //上传图片接口pos 表示第几个图片 
    async handleEditorImgAdd (pos, $file) {
      const formData = new FormData();
      formData.append('file', $file);
      // 从后台获取图片上传后地址
      const res = uploadFileApi(formData)
      const url = res.data.url;
      this.$refs.md.$img2Url(pos, url);  //这里就是引用ref = md 然后调用$img2Url方法即可替换地址
    },
    // 删除图片
    handleEditorImgDel () {
      console.log('handleEditorImgDel');    //我这里没做什么操作,
    },
    // 不添加此方法导航点击失效
    addUrl () {
      this.$nextTick(function () {
        let _aList = document.querySelectorAll(".v-note-navigation-content a");
        for (let i = 0; i < _aList.length; i++) {
          let _aParent = _aList[i].parentNode;
          let _a = _aParent.firstChild;
          if (!_a.id) continue; // 把不属于导航中的a标签去掉,否则会报错
          let _text = _aParent.lastChild;
          let text = _text.textContent;
          _a.href = "#" + _a.id;
          _a.innerText = text;
          _aParent.removeChild(_text);
        }
      });
    },
  },
}
</script>

4.页面使用 纯展示

1.不需要导航(直接贴完整代码)

<template>
  <div class="">
    <article class="markdown-body" style="text-align:left" v-html="content"></article>
  </div>
</template>

<script>
import { showMarkdownApi } from "@/api/system/user";
export default {
  name: 'MainContent',
  data () {
    return {
      content: ''
    };
  },
  mounted () {
    this.getMarkdown()
  },
  methods: {
    // 获取后台保存的内容
    async getMarkdown () {
      const res = await showMarkdownApi({ format: 'html' })
      this.content = res.data
    },
  }
}
</script>
<style lang='scss' scoped>
.markdown-body {
  box-sizing: border-box;
  min-width: 200px;
  max-width: 98%;
  margin: 0 auto;
  box-shadow: 2px 4px 6px gray;
  padding-left: 20px;
  padding-right: 15px;
  padding-top: 40px;
  padding-bottom: 45px;
  margin-bottom: 100px
}
//这个要配合移动端 不是很理解
@media (max-width: 767px) {
  .markdown-body {
    padding: 15px;
  }
}
</style>

2.需要导航(直接贴完整代码)

<template>
  <div class="">
    <mavon-editor class="md" :toolbars="toolbars" :value="content" :subfield="false" defaultOpen="preview"
      :editable="false" :scrollStyle="true" @navigationToggle="addUrl"></mavon-editor>
  </div>
</template>

<script>
import { showMarkdownApi } from "@/api/system/user";
export default {
  name: 'MainContent',
  data () {
    return {
      toolbars: {
        navigation: true, // 导航目录
      },
      content: ''
    };
  },
  mounted () {
    this.getMarkdown()
  },
  methods: {
    // 获取后台保存的内容
    async getMarkdown () {
      const res = await showMarkdownApi({ format: 'markdown' })
      this.content = res.data
    },
    // 同上 不加此方法导航点击失效
    addUrl () {
      this.$nextTick(function () {
        let _aList = document.querySelectorAll(".v-note-navigation-content a");
        for (let i = 0; i < _aList.length; i++) {
          let _aParent = _aList[i].parentNode;
          let _a = _aParent.firstChild;
          if (!_a.id) continue; // 把不属于导航中的a标签去掉,否则会报错
          let _text = _aParent.lastChild;
          let text = _text.textContent;
          _a.href = "#" + _a.id;
          _a.innerText = text;
          _aParent.removeChild(_text);
        }
      });
    },
  }
}
</script>
<style lang='scss' scoped>
.markdown-body {
  box-sizing: border-box;
  min-width: 200px;
  max-width: 80%;
  margin: 0 auto;
  box-shadow: 2px 4px 6px gray;
  padding-left: 20px;
  padding-right: 15px;
  padding-top: 40px;
  padding-bottom: 45px;
  margin-bottom: 100px
}
//这个要配合移动端 不是很理解
@media (max-width: 767px) {
  .markdown-body {
    padding: 15px;
  }
}
</style>

结尾附上源码地址

mavon-editor