vue中組件如何使用vue-quill-editor
一、使用vue-quill-editor富文本組件
1.下載依賴
yarn add vue-quill-editor yarn add quill


2.組件文件結(jié)構(gòu)

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>
<!-- 從數(shù)據(jù)庫讀取展示 -->
<div v-html="str" class="ql-editor">
{{ str }}
</div>
</div>
</template>
<script>
import { quillEditor } from 'vue-quill-editor' // 調(diào)用編輯器
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 }], // 標(biāo)題,鍵值對的形式;1、2表示字體大小
[{ 'list': 'ordered' }, { 'list': 'bullet' }], // 列表
[{ 'script': 'sub' }, { 'script': 'super' }], // 上下標(biāo)
[{ 'indent': '-1' }, { 'indent': '+1' }], // 縮進
[{ 'direction': 'rtl' }], // 文本方向
[{ 'size': ['small', false, 'large', 'huge'] }], // 字體大小
[{ 'header': [1, 2, 3, 4, 5, 6, false] }], // 幾級標(biāo)題
[{ 'color': [] }, { 'background': [] }], // 字體顏色,字體背景顏色
[{ 'font': [false, 'heiti', 'songti', 'kaiti', 'lishu', 'arial', 'monospace'] }], // 字體
[{ 'align': [] }], // 對齊方式
['clean'], // 清除字體樣式
['image', 'video'] // 上傳圖片、上傳視頻
]
}
}
}
},
computed: {
// 當(dāng)前富文本實例
editor () {
return this.$refs.myQuillEditor.quill
}
},
mounted () {
const content = ''// 請求后臺返回的內(nèi)容字符串
this.str = this.escapeStringHTML(content)
},
methods: {
onEditorReady (editor) { // 準(zhǔn)備編輯器
},
onEditorBlur () {}, // 失去焦點事件
onEditorFocus () {}, // 獲得焦點事件
onEditorChange () {
this.$emit('change', this.escapeStringHTML(this.content))
}, // 內(nèi)容改變事件
// 轉(zhuǎn)碼
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: '標(biāo)題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: '標(biāo)題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: '標(biāo)題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: '標(biāo)題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: '標(biāo)題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: '標(biāo)題6';
}
.ql-snow .ql-picker.ql-font .ql-picker-label::before,
.ql-snow .ql-picker.ql-font .ql-picker-item::before {
content: '標(biāo)準(zhǔn)字體';
}
.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' // 調(diào)用編輯器
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
// 設(shè)置請求頭部
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 // 這里寫入請求返回的數(shù)據(jù),也就是一個圖片字符串
}
},
toolbar: {
container: container,
handlers: {
'image': function () {
QuillWatch.emit(this.quill.id)
}
}
}
}
}
}
},
computed: {
// 當(dāng)前富文本實例
editor () {
return this.$refs.myQuillEditor.quill
}
},
mounted () {
},
methods: {
onEditorReady (editor) { // 準(zhǔn)備編輯器
},
onEditorBlur () {}, // 失去焦點事件
onEditorFocus () {}, // 獲得焦點事件
onEditorChange () {
this.$emit('change', this.escapeStringHTML(this.content))
}, // 內(nèi)容改變事件
// 轉(zhuǎn)碼
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: '標(biāo)題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: '標(biāo)題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: '標(biāo)題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: '標(biāo)題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: '標(biāo)題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: '標(biāo)題6';
}
.ql-snow .ql-picker.ql-font .ql-picker-label::before,
.ql-snow .ql-picker.ql-font .ql-picker-item::before {
content: '標(biāo)準(zhǔn)字體';
}
.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)
設(shè)置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 // 這里寫入請求返回的數(shù)據(jù),也就是一個圖片字符串
}
},
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'
})
)

最后重啟項目
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue-video-player實現(xiàn)實時視頻播放方式(監(jiān)控設(shè)備-rtmp流)
這篇文章主要介紹了vue-video-player實現(xiàn)實時視頻播放方式(監(jiān)控設(shè)備-rtmp流),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08
element日期選擇器el-date-picker樣式圖文詳解
最近寫的項目里面有一個功能是日期選擇功能,第一反應(yīng)是使用element里面的el-date-picker組件,下面這篇文章主要給大家介紹了關(guān)于element日期選擇器el-date-picker樣式的相關(guān)資料,需要的朋友可以參考下2022-09-09
Vue+axios使用FormData方式向后端發(fā)送數(shù)據(jù)
在前后端分離的項目中經(jīng)常使用到Vue+axios通過FormData的方式向后端發(fā)送表單數(shù)據(jù),下面就來介紹一下如何實現(xiàn),感興趣的可以了解一下2023-09-09
vue中v-for通過動態(tài)綁定class實現(xiàn)觸發(fā)效果
這篇文章主要介紹了vue中v-for通過動態(tài)綁定class實現(xiàn)觸發(fā)效果,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2018-12-12
vue3+Naive?UI數(shù)據(jù)表格基本使用方式詳解
這篇文章主要給大家介紹了關(guān)于vue3+Naive?UI數(shù)據(jù)表格基本使用方式詳?shù)南嚓P(guān)資料,Naive?UI是一個基于Typescript開發(fā)的針對Vue3開發(fā)的UI組件庫,由TuSimple(圖森未來)公司開發(fā)并開源,需要的朋友可以參考下2023-08-08
VUE+Canvas 實現(xiàn)桌面彈球消磚塊小游戲的示例代碼
這篇文章主要介紹了VUE+Canvas 實現(xiàn)桌面彈球消磚塊小游戲,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-04-04
解決vuex數(shù)據(jù)異步造成初始化的時候沒值報錯問題
今天小編大家分享一篇解決vuex數(shù)據(jù)異步造成初始化的時候沒值報錯問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-11-11
vue實現(xiàn)下拉框二級聯(lián)動效果的實例代碼
這篇文章主要介紹了vue實現(xiàn)下拉框二級聯(lián)動效果,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-11-11

