vue integrated rich text tinymce

Keywords: Javascript axios JSON Vue

development environment

1. vscode

development language

1. vue
2. javaScript

Plug-in installation

1. npm install tinymce -S
 2. You can use the files in it. After downloading, you can view the following directory structure in node modules
    

3. The whole structure can be copied into static. In order to save the size of the packed file, tinymce.min.js can be imported as cdn and put into index.html
    <script src="https://cdnjs.cloudflare.com/ajax/libs/tinymce/4.7.5/tinymce.min.js"></script>
4. The enclosed code can be imported and used directly
   
    <template>

<div>

<textarea :id="Id"></textarea>

</div>
</template>
<script>
Import "TinyMCE / Langs / zh CN. JS"; / / import Chinese package address
//import axios from "axios"; / / you can import axios files to upload pictures
export default {
data() {

const Id = Date.now();
return {
  Id: Id, // A selector for constructing tinymce
  Editor: null,
  tinymceConfig: {
    // GLOBAL
    height: 500,
    theme: "modern",
    menubar: false,
    toolbar: `styleselect | fontselect | formatselect | fontsizeselect | forecolor backcolor | bold italic underline strikethrough | image  media | table | alignleft aligncenter alignright alignjustify | outdent indent | numlist bullist | preview removeformat  hr | paste code  link | undo redo | fullscreen `,
    plugins: `
        paste
        importcss
        image
        code
        table
        advlist
        fullscreen
        link
        media
        lists
        textcolor
        colorpicker
        hr
        preview
    `,

    // CONFIG

    forced_root_block: "p",
    force_p_newlines: true,
    importcss_append: true,
    skin_url: "/static/tinymce/skins/lightgray", // You can import the files under node modules into static and then import them here
    language_url: "/static/tinymce/langs/zh_CN.js", // Import Chinese package
    language: "zh_CN",

    // CONFIG: ContentStyle is very important. You need to write this basic style on the last rendered page to ensure consistency. The problem of 'table' and 'img' basically depends on this
    content_style: `
        *                         { padding:0; margin:0; }
        html, body                { height:100%; }
        img                       { max-width:100%; display:block;height:auto; }
        a                         { text-decoration: none; }
        iframe                    { width: 100%; }
        p                         { line-height:1.6; margin: 0px; }
        table                     { word-wrap:break-word; word-break:break-all; max-width:100%; border:none; border-color:#999; }
        .mce-object-iframe        { width:100%; box-sizing:border-box; margin:0; padding:0; }
        ul,ol                     { list-style-position:inside; }
    `,

    insert_button_items: "image link | inserttable",

    // CONFIG: Paste
    paste_retain_style_properties: "all",
    paste_word_valid_elements: "*[*]", // word needs it
    paste_data_images: true, // Paste at the same time can automatically upload the pictures in the content, very powerful function
    paste_convert_word_fake_lists: false, // This property is required to insert a word document
    paste_webkit_styles: "all",
    paste_merge_formats: true,
    nonbreaking_force_tab: false,
    paste_auto_cleanup_on_paste: false,

    // CONFIG: Font
    fontsize_formats: "10px 11px 12px 14px 16px 18px 20px 24px",

    // CONFIG: StyleSelect
    style_formats: [
      {
        title: "text-indent",
        block: "p",
        styles: { "text-indent": "2em" }
      },
      {
        title: "Row height",
        items: [
          { title: "1", styles: { "line-height": "1" }, inline: "span" },
          {
            title: "1.5",
            styles: { "line-height": "1.5" },
            inline: "span"
          },
          { title: "2", styles: { "line-height": "2" }, inline: "span" },
          {
            title: "2.5",
            styles: { "line-height": "2.5" },
            inline: "span"
          },
          { title: "3", styles: { "line-height": "3" }, inline: "span" }
        ]
      }
    ],

    // FontSelect
    font_formats: `
        //Microsoft YaHei = Microsoft YaHei;
        //Tahoma = Tahoma;
        //Bold = bold;
        //Fangsong = Fangsong;
        //Regular script = regular script;
        //Official script = official script;
        //Round = round;
        Andale Mono=andale mono,times;
        Arial=arial, helvetica,
        sans-serif;
        Arial Black=arial black, avant garde;
        Book Antiqua=book antiqua,palatino;
        Comic Sans MS=comic sans ms,sans-serif;
        Courier New=courier new,courier;
        Georgia=georgia,palatino;
        Helvetica=helvetica;
        Impact=impact,chicago;
        Symbol=symbol;
        Tahoma=tahoma,arial,helvetica,sans-serif;
        Terminal=terminal,monaco;
        Times New Roman=times new roman,times;
        Trebuchet MS=trebuchet ms,geneva;
        Verdana=verdana,geneva;
        Webdings=webdings;
        Wingdings=wingdings,zapf dingbats`,

    // Tab
    tabfocus_elements: ":prev,:next",
    object_resizing: true,

    // Image
    imagetools_toolbar:
      "rotateleft rotateright | flipv fliph | editimage imageoptions"
  }
};

},
props: {

value: {
  default: "",
  type: String
},
config: {
  type: Object,
  default: () => {
    return {
      theme: "modern",
      height: 300
    };
  }
},
// This parameter is the url of the uploaded file
url: {
  default: "",
  type: String
},
//Upload file type
accept: {
  default: "image/jpeg, image/png, image/jpg,",
  type: String
},
maxSize: {
  default: 2097152,
  type: Number
},
withCredentials: {
  default: false,
  type: Boolean
}

},
mounted() {

this.init();

},
beforeDestroy() {

// Destroy tinymce
//   window.tinymce.remove(`$#{this.Id}`)

},
methods: {

init() {
  const self = this;

  this.Editor = window.tinymce.init({
    // Default configuration
    ...this.tinymceConfig,

    // Picture upload
    images_upload_handler: function(blobInfo, success, failure, progress) {
      if (blobInfo.blob().size > self.maxSize) {
        failure("Too large file size");
      }
      if (self.accept.indexOf(blobInfo.blob().type) > -1) {
        uploadPic();
      } else {
        failure("Picture format error");
      }
      function uploadPic() {
        // Upload files with axios
        // progress(0);
        // let param = new FormData();
        // let config = {
        //   headers: {
        //     "Content-Type": "multipart/form-data"
        //   }
        // };
        // param.append("file", blobInfo.blob());
        // console.log('axios', axios);
        // axios
        //   .post("http://operate-dev.winchaingroup.com/api/upload", param, config)
        //   .then(response => {
        //     success(response.data.data);
        //     self.$emit("on-upload-complete", [json, success, failure]);
        //     progress(100);
        //   })
        //   .catch(error => {
        //     console.log("err", error);
        //   });

        // Upload files with ajax
        const xhr = new XMLHttpRequest();
        let createFrom = document.createElement("form");
        let FromData = new FormData(createFrom);
        xhr.withCredentials = self.withCredentials;
        xhr.open("POST", self.url);
        xhr.onload = function() {
          if (xhr.status !== 200) {
            // Throw 'on upload fail' hook
            failure("Upload failure: " + xhr.status);
            return;
          }
          const json = JSON.parse(xhr.responseText);
          // The parameter in the success function is the url returned by the uploaded file
          success(json.data);
          progress(100);
          // Throw 'on upload complete' hook
        };
        FromData.append("file", blobInfo.blob());
        xhr.send(FromData);
      }
    },

    // config passed in from prop
    ...this.config,

    // Mounted DOM object
    selector: `#${this.Id}`,
    setup: editor => {
      // Throw 'on ready' event hook
      editor.on("init", () => {
        self.loading = false;
        editor.setContent(self.value);
      });
      // Throw 'input' event hook to synchronize value data
      editor.on("input change undo redo", () => {});
    }
  });
}

}
};
</script>

5. Import in component to use
    import tinymce from './tinymce/index'

Quote

https://Www.bootcdn.cn/tinymce/ / / TinyMCE address

Posted by spasme on Sun, 08 Dec 2019 21:23:47 -0800