VUE rich text wangEditor v4 version adds source code mode to be used in combination with Monaco Editor

VUE has found a lot of open source libraries for rich text, and found that the star of wangEditor Github should be trustworthy at most.
However, during the use process, I found that wangEditor does not have a source code mode, and the document also states that it needs to be connected by itself.

wangEditor official document

So I wrote an example of using it in combination with Monaco Editor

Don't talk nonsense, let's start with the effect

  • wangEditor effect

  • Monaco Editor effect
    insert image description here

// 在需要使用富文本 使用自己 封装自定义的组件

import Wangeditor from "@/components/customEditor";

 <customEditor
     v-model="value"
 />

customEditor.vue

//  customEditor
<template lang="html">
  <div>
    <editor v-if="!showCode" :height="height"  @change="changeValue" :value="value" />
    <monaco v-else :height="height"  @change="changeValue" :value="value" />
    <div class="bottom"><el-link  :underline="false" @click="showCode = !showCode"><i class="el-icon-view el-icon--right"></i>  
    {
    
    {
    
     showCode?"可视化界面":"查看源码"}}</el-link></div>
  </div>
</template>

<script>
import monaco from "./monaco";
import editor from "./editor";

export default {
    
    
  components:{
    
    
    monaco,editor
  },
  data() {
    
    
    return {
    
    
      showCode:false, // 是否查看源码
    };
  },
  props: {
    
    
    value: {
    
    
      type: String,
      default: "",
    },
    height: {
    
    
      type: Number,
      default: 0,
    }
  },
  mounted() {
    
    
   
  },
  methods: {
    
    
  		// wangEditor/Monaco Editor 改变的值做保存
      changeValue(value){
    
    
         this.$emit("input",value)
      }
  },
};
</script>
<style scoped>
.bottom{
    
    
  border-bottom: 1px solid #CCC;
   border-right: 1px solid #CCC;
    border-left: 1px solid #CCC;
}
</style>

editor.vue

<template lang="html">
  <div class="editor" v-loading="imgLoading">
    <div ref="toolbar" class="toolbar">
    </div>
    <div ref="editor" class="text" :style="{height: height ? height + 'px' : ''}">
    </div>
  </div>
</template>

<script>
import E from 'wangeditor'
export default {
    
    
  data () {
    
    
    return {
    
    
      editor: null,
      info_: null,
      imgLoading: false
    }
  },
  model: {
    
    
    prop: 'value',
    event: 'change'
  },
  props: {
    
    
    value: {
    
    
      type: String,
      default: ''
    },
    height: {
    
    
      type: Number,
      default: 0
    },
    isClear: {
    
    
      type: Boolean,
      default: false
    }
  },
  watch: {
    
    
    isClear (val) {
    
    
      // 触发清除文本域内容
      if (val) {
    
    
        this.editor.txt.clear()
        this.info_ = null
      }
    },
    value (val) {
    
    
      // 保证光标不会重新回到最后
      if (val != this.info_){
    
    
        // 使用 v-model 时,设置初始值
        this.editor.txt.html(val)
      }
    }
  },
  mounted () {
    
    
    this.seteditor()
  },
  methods: {
    
    
    seteditor () {
    
    
      const _this = this
      this.editor = new E(this.$refs.toolbar, this.$refs.editor)
      this.editor.config.zIndex = 0
      this.editor.config.uploadImgShowBase64 = false // base 64 存储图片
      this.editor.config.uploadImgServer = process.env.VUE_APP_BASE_API + '/common/upload'// 配置服务器端地址
      this.editor.config.uploadImgHeaders = {
    
          }// 自定义 header
      this.editor.config.uploadFileName = 'file' // 后端接受上传文件的参数名
      this.editor.config.uploadImgMaxSize = 2 * 1024 * 1024 // 将图片大小限制为 2M
      this.editor.config.uploadImgMaxLength = 6 // 限制一次最多上传 3 张图片
      this.editor.config.uploadImgTimeout = 3 * 60 * 1000 // 设置超时时间
      
      this.editor.config.uploadImgHooks = {
    
    
        // 上传图片之前
        before: function(xhr) {
    
    
            _this.imgLoading = true
        },
        fail: (xhr, editor, result) => {
    
    
          // 插入图片失败回调
          _this.imgLoading = false
        },
        success: (xhr, editor, result) => {
    
    
          // 图片上传成功回调
           _this.imgLoading = false
        },
        timeout: (xhr, editor) => {
    
    
          // 网络超时的回调
          _this.imgLoading = false
        },
        error: (xhr, editor,resData) => {
    
    
          // 图片上传错误的回调
          _this.imgLoading = false
        },
        customInsert: (insertImg, result, editor) => {
    
    
          // 图片上传成功,插入图片的回调
          if(result.code == 200){
    
    
            _this.editor.cmd.do('insertHTML', '<img src='+result.data+' />')
          }else{
    
    
            _this.$message.error('上传图片失败')
          }
          _this.imgLoading = false
        }
      }
      this.editor.config.customAlert = function (s) {
    
    
          _this.$message.error(s)
      }
      this.editor.config.onchange = (html) => {
    
    
        _this.info_ = html // 绑定当前逐渐地值
        _this.$emit('change', _this.info_) // 将内容同步到父组件中
      }
      // 创建富文本编辑器
      this.editor.create()
      if  (this.value){
    
    
        this.editor.txt.html(this.value)
      }
    }
  },
   beforeDestroy() {
    
    
    this.editor.destroy()
    this.editor = null
  }
}
</script>

<style lang="css">
.editor {
    
    
  width: 100%;
  margin: 0 auto;
}
.toolbar {
    
    
  border: 1px solid #ccc;
}
.text {
    
    
  border: 1px solid #ccc;
  min-height: 500px;
}
.w-e-text-container{
    
    
  height: 490px !important;
}
</style>

monaco.view

<template>
     <div  
        ref="code_box"  class="text" :style="{height: height ? height + 'px' : ''}">
    </div>
</template>


<script>
import * as monaco from "monaco-editor";

export default {
    
    
  data() {
    
    
    return {
    
    
      monacoInstance: null,
    };
  },
  props: {
    
    
     height: {
    
    
      type: Number,
      default: 0,
    },
    value: {
    
    
      type: String,
      default: "",
    },
  },
  mounted() {
    
    
    this.seteditor();
  },
  methods: {
    
    
    setValue(val){
    
    
        // this.monacoInstance.setValue(val)
    },
    seteditor() {
    
    
      // 初始化编辑器实例

      this.monacoInstance = monaco.editor.create(this.$refs.code_box, {
    
    
          value: this.value,
        theme: "vs", // vs, hc-black, or vs-dark

        language: "html", // shell、sql、python

        readOnly: false, // 不能编辑
      });
      // 编辑器内容发生改变时触发
      this.monacoInstance.onDidChangeModelContent(() => {
    
    
        this.$emit('change', this.monacoInstance.getValue())
      });
    },
  },
  beforeDestroy() {
    
    
    this.monacoInstance.dispose();
    this.monacoInstance = null;
  },
};
</script>

<style lang="css">
.editor {
    
    
  width: 100%;
  margin: 0 auto;
}
.toolbar {
    
    
  border: 1px solid #ccc;
}
.text {
    
    
  border: 1px solid #ccc;
  min-height: 500px;
}
.w-e-text-container {
    
    
  height: 490px !important;
}
</style>

Remember the library corresponding to npm install

npm install -u wangeditor   
npm install monaco-editor 
npm install monaco-editor-webpack-plugin

Guess you like

Origin blog.csdn.net/abc564643122/article/details/121543635