wangEditor rich text editor with vue+elementUI

Collected from the Internet, it seems that tinymce and wangEditor are used more.

tinymce document address https://www.tiny.cloud/docs/

Support image online processing, plug-ins, strong function, excellent editing ability, good interface. The document is in English and can be translated by Google.

wangEditor document address: http://www.wangedit.com/

js and css implementation, lightweight and simple, open source and complete Chinese documents. The UI is beautiful and the plug-ins can basically meet the needs.

Because English is not good, we choose wangEditor first.

Use steps:

1, installation

npm install wangeditor --save

2, template

The self-defined template uses the self-control upload process according to the document instructions, and adds the response processing for deleting pictures.

<template lang="html">
  <div class="editor">
    <div ref="toolbar" class="toolbar">
    </div>
    <div ref="editor"
      v-loading="fullloading"
      element-loading-text="Desperately loading"
      element-loading-spinner="el-icon-loading"
      element-loading-background="rgba(0, 0, 0, 0.8)" width="180px"
     class="text">
    </div>
  </div>
</template>


<script>
  import { base_encode } from "@/utils/base64.js";
  import { GetShort,DeleteSpecialWord } from "@/utils/localstore.js";
  import E from 'wangeditor'

  export default {
    name: 'editoritem',
    data() {
      return {
        editor: null,
        info_: null,
        fullloading:false,
        delete_file:[],
      }
    },
    model: {
      prop: 'value',
      event: 'change'
    },
    props: {
      value: {
        type: String,
        default: ''
      },
      isClear: {
        type: Boolean,
        default: false
      }
    },
    watch: {
      isClear(val) {
        // Trigger clear text field content
        if (val) {
          this.editor.txt.clear()
          this.info_ = null
        }
      },
      value: function(value) {
        if (value !== this.editor.txt.html()) {
          this.editor.txt.html(this.value)
        }
      }
      //Value is the input of the edit box. Here I listen to the value. When the parent component calls, if the value is assigned, the child component will display the value assigned by the parent component
    },
    mounted() {
      this.seteditor()
      this.editor.txt.html(this.value)
    },
    methods: {
      seteditor() {
        this.editor = new E(this.$refs.toolbar, this.$refs.editor)
        this.editor.customConfig.uploadImgShowBase64 = false // base 64 store pictures
        // This. Editor. CustomConfig. Uploadimgserver ='http://otp.cdinfotech.top/file/upload_images' / / configure the server-side address
        // This. Editor. CustomConfig. Uploadimgheeaders = {} / / custom header s
        // This. Editor. CustomConfig. Uploadfilename ='File '/ / the parameter name of the upload file accepted by the backend
        this.editor.customConfig.uploadImgMaxSize = 2 * 1024 * 1024 // Limit picture size to 2M
        this.editor.customConfig.uploadImgMaxLength = 6   // Limit to upload up to 3 pictures at a time
        this.editor.customConfig.uploadImgTimeout = 3 * 60 * 1000 // Set timeout
        this.editor.customConfig.showLinkImg = false      // Hide network picture tab

        // Configuration menu
        this.editor.customConfig.menus = [
          'head', // Title
          'bold', // bold
          'fontSize', // Font size
          'fontName', // Typeface
          'italic', // Italics
          'underline', // Underline
          'strikeThrough', // Delete line
          'foreColor', // Text color
          'backColor', // background color
          'link', // Insert link
          'list', // list
          'justify', // Alignment mode
          'quote', // Quote
          'emoticon', // Expression
          'image', // Insert picture
          'table', // form
          'video', // Insert video
          'code', // Insert code
          'undo', // Revoke
          'redo', // repeat
          'fullscreen' // Full screen
        ]

        // Newly added
        var vue_this=this;
        this.delete_file=[];  //Reset

        // Using custom upload image method
        this.editor.customConfig.customUploadImg =function (files, insert) {
          // Files are list 1 or more files selected in input
          // console.log(files);
          vue_this.fullloading=true;

          for(var i=0;i<files.length;i++){            
            // console.log(files[i].name+' '+files[i].type+' '+files[i].size);
            var f_name="",f_type="",f_size="";
            f_name=files[i].name;
            f_type=files[i].type;
            f_size=files[i].size;

            var tf = new FileReader();
            tf.readAsDataURL(files[i]);
            tf.onload = function() {
                var postdata = "";  

                postdata =
                '{"action":"'+''+'","user_no":"' +
                '' +
                '","upfile_name":"' +
                DeleteSpecialWord(f_name) +
                '","upfile_type":"' +
                f_type +
                '","upfile_size":"' +
                f_size +
                '","upfile_data":"' +
                this.result +
                '","sheet_no":"' +
                '' +
                '"}';

                postdata =
                  '{"method":"File_book_add","data":"' + base_encode(postdata) + '"}';            
                vue_this.$post(
                  "/Data_Back",
                  postdata,
                ).then(res => {
                  vue_this.fullloading=false;
                  try {         
                    res=JSON.parse(res); 
                    // console.log(res);  
                    if (res.data.status == 1) {
                      vue_this.$message({message:'Upload success!',type:'success'});
                      // console.log('upload succeeded ');
                      insert(res.data.url); //Insert into interface

                      vue_this.delete_file.push(res.data.path); //Returns the unique path to the picture. If not, delete the image on the corresponding server
                    } else {
                      vue_this.$message({message:'Upload failure!',type:'warning'});
                      // console.log('upload failed ');
                    }
                  } catch (ex) {
                    vue_this.$message.error('A mistake!'+ex);
                    // console.log('error! '+ex);
                  }
                });



            };

            

          }         
          // Insert is the method to insert into the editor after getting the picture url
          

          // For example: if you upload a picture successfully, the server returns the format {url: 'here is the server's access to the picture link'} to insert the picture as follows:
          // var url = result.url
          // After passing the code and returning the result, insert the picture into the editor
          // Insert method can insert base64 picture encoding and picture linking
          // insert(url)
        }
        
        this.editor.customConfig.onchange = (html) => {
          this.info_ = html // Binding current gradual value

          // Delete pictures
          for(var i=0;i<vue_this.delete_file.length;i++){
            
            if(this.info_.indexOf(vue_this.delete_file[i])>=0){
              continue;
            }else{
              // Not found, delete the corresponding picture on the server
              // console.log('delete object '+ Vue [this. Delete [file [i]);

              var postdata="";

              postdata =
                '{"method":"File_book_del","data":"' + base_encode(vue_this.delete_file[i]) + '"}';  
                
              vue_this.delete_file.splice(i,1);

              vue_this.$post(
                "/Data_Back",
                postdata,
              ).then(res => {
                try {         
                  res=JSON.parse(res); 
                  // console.log(res); 
                } catch (ex) {
                  // console.log('error! '+ex);
                }
              });

            }
          }

          this.$emit('change', this.info_) // Synchronize content to parent component
        }
        // Create rich text editor
        this.editor.create()

        
      }
    }
  }
</script>

<style lang="css">
  .editor {
    width: 100%;
    margin: 0 auto;
    position: relative;
    z-index: 0;
  }
  .toolbar {
    border: 1px solid #ccc;
  }
  .text {
    border: 1px solid #ccc;
    min-height: 500px;
  }
</style>

3. Parent component introduction

<template>
  <div>
       <bookedit v-model="detail" :isClear="isClear" @change="change"></bookedit>         
  </div>
</template>

<script>

export default {  
  components: {    
    'bookedit':()=>import("../personmode/bookedit.vue"),  
  },
  data() {    
    return {      
      isClear: false,       /* Rich text judgment */
      detail:"",            /* Rich text content */
    };
  },
  methods: {    
    change(val) {
      console.log(val)   
      // You can cancel it here if you don't need it
    },
  }
    
}

</script>
<style scoped>

</style>

Tags: Front-end JSON Vue Google npm

Posted on Fri, 10 Jan 2020 11:14:57 -0500 by weazy