1.0.0 • Published 4 years ago

vue-quill-editon-imagepaste v1.0.0

Weekly downloads
-
License
MIT
Repository
-
Last release
4 years ago

实现一个 vue-quill-editor 插件

官网文档

https://github.surmon.me/vue-quill-editor/

一般的使用参考文档的是使用方法,参考如下

<template>
  <div class="example">
    <quill-editor
      class="editor"
      ref="myTextEditor"
      :value="content"
      :options="editorOption"
      @change="onEditorChange"
      @blur="onEditorBlur($event)"
      @focus="onEditorFocus($event)"
      @ready="onEditorReady($event)"
    />
    <div class="output code">
      <code class="hljs" v-html="contentCode"></code>
    </div>
    <div class="output ql-snow">
      <div class="ql-editor" v-html="content"></div>
    </div>
  </div>
</template>

<script>
  import dedent from 'dedent'
  import hljs from 'highlight.js'
  import debounce from 'lodash/debounce'
  import { quillEditor } from 'vue-quill-editor'
  // highlight.js style
  import 'highlight.js/styles/tomorrow.css'
  // import theme style
  import 'quill/dist/quill.core.css'
  import 'quill/dist/quill.snow.css'
  export default {
    name: 'quill-example-snow',
    title: 'Theme: snow',
    components: {
      quillEditor
    },
    data() {
      return {
        editorOption: {
          modules: {
            toolbar: [
              ['bold', 'italic', 'underline', 'strike'],
              ['blockquote', 'code-block'],
              [{ 'header': 1 }, { 'header': 2 }],
              [{ 'list': 'ordered' }, { 'list': 'bullet' }],
              [{ 'script': 'sub' }, { 'script': 'super' }],
              [{ 'indent': '-1' }, { 'indent': '+1' }],
              [{ 'direction': 'rtl' }],
              [{ 'size': ['small', false, 'large', 'huge'] }],
              [{ 'header': [1, 2, 3, 4, 5, 6, false] }],
              [{ 'font': [] }],
              [{ 'color': [] }, { 'background': [] }],
              [{ 'align': [] }],
              ['clean'],
              ['link', 'image', 'video']
            ],
            syntax: {
              highlight: text => hljs.highlightAuto(text).value
            }
          }
        },
        content: dedent`
          <h1 class="ql-align-center"><span class="ql-font-serif" style="background-color: rgb(240, 102, 102); color: rgb(255, 255, 255);"> I am snow example! </span></h1><p><br></p><p><span class="ql-font-serif">W Can a man still be brave if he's afraid? That is the only time a man can be brave. </span></p><p><br></p><p><strong class="ql-font-serif ql-size-large">Courage and folly is </strong><strong class="ql-font-serif ql-size-large" style="color: rgb(230, 0, 0);">always</strong><strong class="ql-font-serif ql-size-large"> just a fine line.</strong></p><p><br></p><p><u class="ql-font-serif">There is only one God, and his name is Death. And there is only one thing we say to Death: "Not today."</u></p><p><br></p><p><em class="ql-font-serif">Fear cuts deeper than swords.</em></p><p><br></p><pre class="ql-syntax" spellcheck="false"><span class="hljs-keyword">const</span> a = <span class="hljs-number">10</span>;
          <span class="hljs-keyword">const</span> editorOption = { <span class="hljs-attr">highlight</span>: <span class="hljs-function"><span class="hljs-params">text</span> =&gt;</span> hljs.highlightAuto(text).value };</pre><p><br></p><p><span class="ql-font-serif">Every flight begins with a fall.</span></p><p><br></p><p><a href="https://surmon.me/" rel="noopener noreferrer" target="_blank" class="ql-font-serif ql-size-small" style="color: rgb(230, 0, 0);"><u>A ruler who hides behind paid executioners soon forgets what death is. </u></a></p><p><br></p><iframe class="ql-video ql-align-center" frameborder="0" allowfullscreen="true" src="https://www.youtube.com/embed/QHH3iSeDBLo?showinfo=0" height="238" width="560"></iframe><p><br></p><p><span class="ql-font-serif">Hear my words, and bear witness to my vow. Night gathers, and now my watch begins. It shall not end until my death. I shall take no wife, hold no lands, father no children. I shall wear no crowns and win no glory. I shall live and die at my post. I am the sword in the darkness. I am the watcher on the walls. I am the fire that burns against the cold, the light that brings the dawn, the horn that wakes the sleepers, the shield that guards the realms of men. I pledge my life and honor to the Night’s Watch, for this night and all the nights to come.</span></p><p><br></p><p><span class="ql-font-serif">We are born to suffer, to suffer can make us strong.</span></p><p><br></p><p><span class="ql-font-serif">The things we love destroy us every time.</span></p>
        `,
      }
    },
    methods: {
      onEditorChange: debounce(function(value) {
        this.content = value.html
      }, 466),
      onEditorBlur(editor) {
        console.log('editor blur!', editor)
      },
      onEditorFocus(editor) {
        console.log('editor focus!', editor)
      },
      onEditorReady(editor) {
        console.log('editor ready!', editor)
      }
    },
    computed: {
      editor() {
        return this.$refs.myTextEditor.quill
      },
      contentCode() {
        return hljs.highlightAuto(this.content).value
      }
    },
    mounted() {
      console.log('this is Quill instance:', this.editor)
    }
  }
</script>

<style lang="scss" scoped>
  .example {
    display: flex;
    flex-direction: column;
    .editor {
      height: 40rem;
      overflow: hidden;
    }
    .output {
      width: 100%;
      height: 20rem;
      margin: 0;
      border: 1px solid #ccc;
      overflow-y: auto;
      resize: vertical;
      &.code {
        padding: 1rem;
        height: 16rem;
      }
      &.ql-snow {
        border-top: none;
        height: 24rem;
      }
    }
  }
</style>

https://github.com/surmon-china/surmon-china.github.io/blob/source/projects/vue-quill-editor/examples/01-theme-snow.vue

实现一个粘贴图片的功能

刚开始接触 vue 的开发,就接了个需求是实现富文本粘贴功能。 直接上代码。

// 输出一个模块
export class ImagePaste {
  //quill 和 options->方便定义一些配置
  constructor(quill, options = {}) {
    // save the quill
    this.quill = quill;
    //绑定事件
    this.handlePaste = this.handlePaste.bind(this);
    // 坚挺粘贴事件
    this.quill.root.addEventListener("paste", this.handlePaste, false);
  }

  //处理粘贴事件
  //还需要根据复制的数据类型作一下判断
  //  读取到剪贴板中的数据 具体的参考使用 可以看下MDN的文档 基本主流的浏览器都支持了
  handlePaste(e) {
    if (
      e.clipboardData &&
      e.clipboardData.items &&
      e.clipboardData.items.length
    ) {
      const clipboardData = e.clipboardData;
      const items = clipboardData.items;
      const item = items[0];
      if (item && item.kind === "file" && item.type.match(/^image\//i)) {
        e.preventDefault()
        this.file = item.getAsFile();
        this.toBase64();
      }
    }
  }

  toBase64() {
    // 转换成base64 也可以压缩图片进行上传
    const reader = new FileReader();
    reader.onload = e => {
      this.insertImg(e.target.result);
    };
    reader.readAsDataURL(this.file);
  }

  insertImg(baseUrl) {
    // 插入文本中
    const currentIndex = this.quill.getSelection().index || 0;
    this.quill.insertEmbed(currentIndex, "image", baseUrl);
    this.quill.setSelection(currentIndex + 1);
    this.quill.update();
    // 更新光标的位置
  }
}

使用

import { quillEditor, Quill } from "vue-quill-editor";
import ImagePaste;

Quill.register("modules/ImagePaste", ImagePaste);

import "quill/dist/quill.core.css";
import "quill/dist/quill.snow.css";
import "quill/dist/quill.bubble.css";

//你的其他代码

https://github.com/NextBoy/quill-image-extend-module

https://github.com/kensnyder/quill-image-drop-module