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"> <!-- 新增時(shí)輸入 --> <quill-editor v-model="content" ref="myQuillEditor" :options="editorOption" @blur="onEditorBlur($event)" @focus="onEditorFocus($event)" @change="onEditorChange($event)" > </quill-editor> <!-- 從數(shù)據(jù)庫(kù)讀取展示 --> <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: '請(qǐng)?jiān)谶@里輸入', modules: { toolbar: [ ['bold', 'italic', 'underline', 'strike'], // 加粗,斜體,下劃線,刪除線 ['blockquote', 'code-block'], // 引用,代碼塊 [{ 'header': 1 }, { 'header': 2 }], // 標(biāo)題,鍵值對(duì)的形式;1、2表示字體大小 [{ 'list': 'ordered' }, { 'list': 'bullet' }], // 列表 [{ 'script': 'sub' }, { 'script': 'super' }], // 上下標(biāo) [{ 'indent': '-1' }, { 'indent': '+1' }], // 縮進(jìn) [{ 'direction': 'rtl' }], // 文本方向 [{ 'size': ['small', false, 'large', 'huge'] }], // 字體大小 [{ 'header': [1, 2, 3, 4, 5, 6, false] }], // 幾級(jí)標(biāo)題 [{ 'color': [] }, { 'background': [] }], // 字體顏色,字體背景顏色 [{ 'font': [false, 'heiti', 'songti', 'kaiti', 'lishu', 'arial', 'monospace'] }], // 字體 [{ 'align': [] }], // 對(duì)齊方式 ['clean'], // 清除字體樣式 ['image', 'video'] // 上傳圖片、上傳視頻 ] } } } }, computed: { // 當(dāng)前富文本實(shí)例 editor () { return this.$refs.myQuillEditor.quill } }, mounted () { const content = ''// 請(qǐng)求后臺(tái)返回的內(nèi)容字符串 this.str = this.escapeStringHTML(content) }, methods: { onEditorReady (editor) { // 準(zhǔn)備編輯器 }, onEditorBlur () {}, // 失去焦點(diǎn)事件 onEditorFocus () {}, // 獲得焦點(diǎn)事件 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: "請(qǐng)輸入鏈接地址:"; } .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: "請(qǐng)輸入視頻地址:"; } .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>
二、此時(shí)上傳的圖片為base64格式,我們需要上傳圖片
下載依賴
yarn add quill-image-extend-module
<template> <div class="edit_container"> <!-- 新增時(shí)輸入 --> <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: '請(qǐng)?jiān)谶@里輸入', modules: { ImageExtend: { loading: true, name: 'fileData', // 更多配置見官方文檔https://www.kancloud.cn/liuwave/quill/1434141 // 設(shè)置請(qǐng)求頭部 headers: (xhr) => { xhr.setRequestHeader('Authorization', Vue.ls.get(ACCESS_TOKEN)) }, action: this.fileUrl, // 這里寫入請(qǐng)求后臺(tái)地址 例如:"http://xxx.xxx.xxx.xxx:xxx/api/file/upload/indexFile", response: (res) => { return res.url // 這里寫入請(qǐng)求返回的數(shù)據(jù),也就是一個(gè)圖片字符串 } }, toolbar: { container: container, handlers: { 'image': function () { QuillWatch.emit(this.quill.id) } } } } } } }, computed: { // 當(dāng)前富文本實(shí)例 editor () { return this.$refs.myQuillEditor.quill } }, mounted () { }, methods: { onEditorReady (editor) { // 準(zhǔn)備編輯器 }, onEditorBlur () {}, // 失去焦點(diǎn)事件 onEditorFocus () {}, // 獲得焦點(diǎn)事件 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: "請(qǐng)輸入鏈接地址:"; } .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: "請(qǐng)輸入視頻地址:"; } .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) // 注冊(cè) Quill.register('modules/resizeImage ', resizeImage)
設(shè)置editorOption對(duì)象
editorOption: { placeholder: '請(qǐng)?jiān)谶@里輸入', modules: { ImageExtend: { loading: true, name: 'fileData', headers: (xhr) => { xhr.setRequestHeader('Authorization', Vue.ls.get(ACCESS_TOKEN)) }, action: this.fileUrl, // 這里寫入請(qǐng)求后臺(tái)地址 例如:"http://xxx.xxx.xxx.xxx:xxx/api/file/upload/indexFile", response: (res) => { return res.url // 這里寫入請(qǐng)求返回的數(shù)據(jù),也就是一個(gè)圖片字符串 } }, 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) } } } } }
此時(shí)瀏覽器會(huì)顯示以下報(bào)錯(cuò)
1.找到項(xiàng)目的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' }) )
最后重啟項(xiàng)目
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue自定義鍵盤信息、監(jiān)聽數(shù)據(jù)變化的方法示例【基于vm.$watch】
這篇文章主要介紹了vue自定義鍵盤信息、監(jiān)聽數(shù)據(jù)變化的方法,結(jié)合實(shí)例形式分析了vue.js基于vm.$watch進(jìn)行事件監(jiān)聽相關(guān)操作技巧,需要的朋友可以參考下2019-03-03vue雙向數(shù)據(jù)綁定指令v-model的用法
這篇文章主要介紹了vue雙向數(shù)據(jù)綁定指令v-model的用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08Vue頁(yè)面內(nèi)公共的多類型附件圖片上傳區(qū)域并適用折疊面板(示例代碼)
本文中實(shí)現(xiàn)的附件上傳區(qū)域支持超多類型附件分類型上傳,并且可根據(jù)特定條件具體展示某些類型的附件上傳,本文給大家分享Vue頁(yè)面內(nèi)公共的多類型附件圖片上傳區(qū)域并適用折疊面板的示例代碼,需要的朋友參考下吧2021-12-12利用Vue模擬實(shí)現(xiàn)element-ui的分頁(yè)器效果
這篇文章主要為大家詳細(xì)介紹了如何利用Vue模擬實(shí)現(xiàn)element-ui的分頁(yè)器效果,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以動(dòng)手嘗試一下2022-11-11