vue中组件如何使用vue-quill-editor

 更新时间:2024年01月16日 08:48:51   作者:是文静的  
这篇文章主要介绍了vue中组件如何使用vue-quill-editor问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

一、使用vue-quill-editor富文本组件

1.下载依赖

yarn add vue-quill-editor
yarn add quill

2.组件文件结构

Editor文件夹下Editor.vue

<template>
  <div class="edit_container">
    <!--  新增时输入 -->
    <quill-editor
      v-model="content"
      ref="myQuillEditor"
      :options="editorOption"
      @blur="onEditorBlur($event)"
      @focus="onEditorFocus($event)"
      @change="onEditorChange($event)"
    >
    </quill-editor>
    <!-- 从数据库读取展示 -->
    <div v-html="str" class="ql-editor">
      {{ str }}
    </div>
  </div>
</template>

<script>
import { quillEditor } from 'vue-quill-editor' // 调用编辑器
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'

export default {
  name: 'Editor',
  components: {
    quillEditor
  },
  data () {
    return {
      content: ``,
      editorOption: {
        placeholder: '请在这里输入',
        modules: {
          toolbar: [
            ['bold', 'italic', 'underline', 'strike'], // 加粗,斜体,下划线,删除线
            ['blockquote', 'code-block'], // 引用,代码块
            [{ 'header': 1 }, { 'header': 2 }], // 标题,键值对的形式;1、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] }], // 几级标题
            [{ 'color': [] }, { 'background': [] }], // 字体颜色,字体背景颜色
            [{ 'font': [false, 'heiti', 'songti', 'kaiti', 'lishu', 'arial', 'monospace'] }], // 字体
            [{ 'align': [] }], // 对齐方式
            ['clean'], // 清除字体样式
            ['image', 'video'] // 上传图片、上传视频
          ]
        }
      }
    }
  },
  computed: {
    // 当前富文本实例
    editor () {
      return this.$refs.myQuillEditor.quill
    }
  },
  mounted () {
    const content = ''// 请求后台返回的内容字符串
    this.str = this.escapeStringHTML(content)
  },
  methods: {
    onEditorReady (editor) { // 准备编辑器
    },
    onEditorBlur () {}, // 失去焦点事件
    onEditorFocus () {}, // 获得焦点事件
    onEditorChange () {
      this.$emit('change', this.escapeStringHTML(this.content))
    }, // 内容改变事件
    // 转码
    escapeStringHTML (str) {
      str = str.replace(/</g, '<')
      str = str.replace(/>/g, '>')
      return str
    }
  }
}
</script>
<style>
.editor {
  line-height: normal !important;
  height: 500px;
}
.ql-snow .ql-tooltip[data-mode=link]::before {
  content: "请输入链接地址:";
}
.ql-snow .ql-tooltip.ql-editing a.ql-action::after {
    border-right: 0px;
    content: '保存';
    padding-right: 0px;
}

.ql-snow .ql-tooltip[data-mode=video]::before {
    content: "请输入视频地址:";
}

.ql-snow .ql-picker.ql-size .ql-picker-label::before,
.ql-snow .ql-picker.ql-size .ql-picker-item::before {
  content: '14px';
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value=small]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=small]::before {
  content: '10px';
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value=large]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=large]::before {
  content: '18px';
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value=huge]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=huge]::before {
  content: '32px';
}

.ql-snow .ql-picker.ql-header .ql-picker-label::before,
.ql-snow .ql-picker.ql-header .ql-picker-item::before {
  content: '文本';
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before {
  content: '标题1';
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before {
  content: '标题2';
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before {
  content: '标题3';
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before {
  content: '标题4';
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before {
  content: '标题5';
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before {
  content: '标题6';
}

.ql-snow .ql-picker.ql-font .ql-picker-label::before,
.ql-snow .ql-picker.ql-font .ql-picker-item::before {
  content: '标准字体';
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=serif]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=serif]::before {
  content: '衬线字体';
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=monospace]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=monospace]::before {
  content: '等宽字体';
}
</style>

Editor文件夹下index.js

import Editor from './Editor'

export default Editor

components文件夹下index.js

import Editor from '@/components/Editor'
export {
  Editor
}

3.使用

<template>
  <div>
    <Editor class="CKEditor" ref="Editor" v-model="content" @change="callbackChangeEditor"></Editor>
  </div>
</template>
<script>
import { Editor } from '@/components'
  export default {
    components: {
      Editor
    },
    data () {
      return {
        content: '',
      }
    },
    mounted () {},
    methods: {
      callbackChangeEditor (value) {
        this.content = value
      },
    }
  }
</script>
<style lang="less" scoped>
</style>

二、此时上传的图片为base64格式,我们需要上传图片

下载依赖

yarn add quill-image-extend-module
<template>
  <div class="edit_container">
    <!--  新增时输入 -->
    <quill-editor
      v-model="content"
      ref="myQuillEditor"
      :options="editorOption"
      @blur="onEditorBlur($event)"
      @focus="onEditorFocus($event)"
      @change="onEditorChange($event)"
    >
    </quill-editor>
  </div>
</template>
<script>
import Vue from 'vue'
import {
  ACCESS_TOKEN
} from '@/store/mutation-types'
import { quillEditor, Quill } from 'vue-quill-editor' // 调用编辑器
import { container, ImageExtend, QuillWatch } from 'quill-image-extend-module'
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'
Quill.register('modules/ImageExtend', ImageExtend)

export default {
  name: 'RichTextEditor',
  components: {
    quillEditor
  },
  props: {
    fileUrl: {
      type: String,
      default: ''
    }
  },
  data () {
    return {
      content: ``,
      editorOption: {
        placeholder: '请在这里输入',
        modules: {
          ImageExtend: {
            loading: true,
            name: 'fileData',
            // 更多配置见官方文档https://www.kancloud.cn/liuwave/quill/1434141
            // 设置请求头部
            headers: (xhr) => {
              xhr.setRequestHeader('Authorization', Vue.ls.get(ACCESS_TOKEN))
            },
            action: this.fileUrl, // 这里写入请求后台地址 例如:"http://xxx.xxx.xxx.xxx:xxx/api/file/upload/indexFile",
            response: (res) => {
              return res.url // 这里写入请求返回的数据,也就是一个图片字符串
            }
          },
          toolbar: {
            container: container,
            handlers: {
              'image': function () {
                QuillWatch.emit(this.quill.id)
              }
            }
          }
        }
      }
    }
  },
  computed: {
    // 当前富文本实例
    editor () {
      return this.$refs.myQuillEditor.quill
    }
  },
  mounted () {
  },
  methods: {
    onEditorReady (editor) { // 准备编辑器
    },
    onEditorBlur () {}, // 失去焦点事件
    onEditorFocus () {}, // 获得焦点事件
    onEditorChange () {
      this.$emit('change', this.escapeStringHTML(this.content))
    }, // 内容改变事件
    // 转码
    escapeStringHTML (str) {
      str = str.replace(/</g, '<')
      str = str.replace(/>/g, '>')
      return str
    }
  }
}
</script>
<style>
img{
  max-width: 100% !important;
  height: auto !important;
}
.editor {
  line-height: normal !important;
  height: 500px;
}
.ql-container{
  height: 500px;
}
.ql-snow .ql-tooltip[data-mode=link]::before {
  content: "请输入链接地址:";
}
.ql-snow .ql-tooltip.ql-editing a.ql-action::after {
    border-right: 0px;
    content: '保存';
    padding-right: 0px;
}

.ql-snow .ql-tooltip[data-mode=video]::before {
    content: "请输入视频地址:";
}

.ql-snow .ql-picker.ql-size .ql-picker-label::before,
.ql-snow .ql-picker.ql-size .ql-picker-item::before {
  content: '14px';
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value=small]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=small]::before {
  content: '10px';
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value=large]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=large]::before {
  content: '18px';
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value=huge]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=huge]::before {
  content: '32px';
}

.ql-snow .ql-picker.ql-header .ql-picker-label::before,
.ql-snow .ql-picker.ql-header .ql-picker-item::before {
  content: '文本';
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before {
  content: '标题1';
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before {
  content: '标题2';
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before {
  content: '标题3';
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before {
  content: '标题4';
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before {
  content: '标题5';
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before {
  content: '标题6';
}

.ql-snow .ql-picker.ql-font .ql-picker-label::before,
.ql-snow .ql-picker.ql-font .ql-picker-item::before {
  content: '标准字体';
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=serif]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=serif]::before {
  content: '衬线字体';
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=monospace]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=monospace]::before {
  content: '等宽字体';
}
</style>

使用

<template>
  <div>
    <Editor class="CKEditor" ref="Editor" v-model="content" @change="callbackChangeEditor" :fileUrl="richTextFileUrl"></Editor>
  </div>
</template>
<script>
import { Editor } from '@/components'
  export default {
    components: {
      Editor
    },
    data () {
      return {
        content: '',
        // 图片上传url的方法
        richTextFileUrl: getWorkOrderUrl(), // http://localhost:8088/api/v1/insideWorkOrder/upload
      }
    },
    mounted () {},
    methods: {
      callbackChangeEditor (value) {
        this.content = value
      },
    }
  }
</script>
<style lang="less" scoped>
</style>

三、图片过大想要拖拽图片改变大小问题

下载依赖

yarn add quill-image-drop-module
yarn add quill-image-resize-module

在组件里引入使用

import resizeImage from 'quill-image-resize-module' // 图片缩放组件引用
import { ImageDrop } from 'quill-image-drop-module'
Quill.register('modules/imageDrop', ImageDrop) // 注册
Quill.register('modules/resizeImage ', resizeImage)

设置editorOption对象

editorOption: {
  placeholder: '请在这里输入',
  modules: {
    ImageExtend: {
      loading: true,
      name: 'fileData',
      headers: (xhr) => {
        xhr.setRequestHeader('Authorization', Vue.ls.get(ACCESS_TOKEN))
      },
      action: this.fileUrl, // 这里写入请求后台地址 例如:"http://xxx.xxx.xxx.xxx:xxx/api/file/upload/indexFile",
      response: (res) => {
        return res.url // 这里写入请求返回的数据,也就是一个图片字符串
      }
    },
    imageDrop: true, // 图片拖拽
    imageResize: { // 放大缩小
      displayStyles: {
        backgroundColor: 'black',
        border: 'none',
        color: 'white'
      },
      modules: ['Resize', 'DisplaySize', 'Toolbar']
    },
    toolbar: {
      container: container,
      handlers: {
        'image': function () {
          QuillWatch.emit(this.quill.id)
        }
      }
    }
  }
}

此时浏览器会显示以下报错

1.找到项目的build/webpack.base.conf.js文件添加如下代码:

var webpack = require('webpack');
module.exports = {
configureWebpack: {
    plugins: [
     ...
      new webpack.ProvidePlugin({
        'window.Quill': 'quill/dist/quill.js',
        'Quill': 'quill/dist/quill.js'
      })
      ...
    ]
  }
}

2.找到根目录下的vue.config.js文件在configureWebpack下修改

const webpack = require('webpack')
module.exports = {
  configureWebpack: {
    plugins: [
      new webpack.ProvidePlugin({
        'window.Quill': 'quill/dist/quill.js',
        Quill: 'quill/dist/quill.js'
      })
    ]
  }
}

按照已有方式添加在configureWebpack下

config.plugins.push(
  new webpack.ProvidePlugin({
    'window.Quill': 'quill/dist/quill.js',
    Quill: 'quill/dist/quill.js'
  })
)

最后重启项目

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

最新评论