1、引入組件
<quill-editor ref="myQuillEditor" v-model="content" class="editor ql-editor" :options="editorOption" @blur="onEditorBlur($event)" @focus="onEditorFocus($event)" @change="onEditorChange($event)" @ready="ready($event)" />
// 工具欄配置 import { quillEditor } from 'vue-quill-editor' import { Uploads } from '@/api/hpms/qiniu' import 'quill/dist/quill.core.css' import 'quill/dist/quill.snow.css' import 'quill/dist/quill.bubble.css'
2、設置行高
//lineHeight.js import Quill from "quill"; const Parchment = Quill.import("parchment"); class lineHeightAttributor extends Parchment.Attributor.Style { } const lineHeightStyle = new lineHeightAttributor("lineHeight", "line-height", { scope: Parchment.Scope.INLINE, whitelist: ["1", "2", "3", "4", "5"] }); export { lineHeightStyle };
import { lineHeightStyle } from "./lineHeight";
ready() { Quill.register({ "formats/lineHeight": lineHeightStyle }, true) },
editorOption: { placeholder: '您想說點什么?', theme: 'snow', // or 'bubble' modules: { toolbar: { container: toolbarOptions, // container: "#toolbar", handlers: { lineHeight: (value) => { if (value) { const quill = this.$refs.myQuillEditor.quill quill.format("lineHeight", value); } } } } } },
3、行高樣式
.ql-snow .ql-picker.ql-lineHeight .ql-picker-label::before { content: "行高"; } .ql-snow .ql-picker.ql-lineHeight .ql-picker-item[data-value="1"]::before,.ql-snow .ql-picker.ql-lineHeight .ql-picker-label[data-value="1"]::before { content: "行高1"; } .ql-snow .ql-picker.ql-lineHeight .ql-picker-item[data-value="1.5"]::before, .ql-snow .ql-picker.ql-lineHeight .ql-picker-label[data-value="1.5"]::before { content: "行高1.5"; } .ql-snow .ql-picker.ql-lineHeight .ql-picker-item[data-value="1.75"]::before,.ql-snow .ql-picker.ql-lineHeight .ql-picker-label[data-value="1.75"]::before { content: "行高1.75"; } .ql-snow .ql-picker.ql-lineHeight .ql-picker-item[data-value="2"]::before,.ql-snow .ql-picker.ql-lineHeight .ql-picker-label[data-value="2"]::before { content: "行高2"; } .ql-snow .ql-picker.ql-lineHeight .ql-picker-item[data-value="3"]::before,.ql-snow .ql-picker.ql-lineHeight .ql-picker-label[data-value="3"]::before { content: "行高3"; } .ql-snow .ql-picker.ql-lineHeight .ql-picker-item[data-value="4"]::before,.ql-snow .ql-picker.ql-lineHeight .ql-picker-label[data-value="4"]::before { content: "行高4"; } .ql-snow .ql-picker.ql-lineHeight .ql-picker-item[data-value="5"]::before ,.ql-snow .ql-picker.ql-lineHeight .ql-picker-label[data-value="5"]::before{ content: "行高5"; } .ql-snow .ql-picker.ql-lineHeight { width: 70px; }
4、效果圖
5、完整代碼
<template> <div> <!-- 圖片上傳組件輔助--> <el-upload v-show="false" class="avatar-uploader" action="/bmms/web-bm/file" name="img" accept=".jpg, .png" :show-file-list="false" :on-change="handleChange" :http-request="httpRequest" :before-upload="beforeUpload" /> <quill-editor ref="myQuillEditor" v-model="content" class="editor ql-editor" :options="editorOption" @blur="onEditorBlur($event)" @focus="onEditorFocus($event)" @change="onEditorChange($event)" @ready="ready($event)" /> </div> </template> <script> // 工具欄配置 import { quillEditor } from 'vue-quill-editor' import { Uploads } from '@/api/hpms/qiniu' import 'quill/dist/quill.core.css' import 'quill/dist/quill.snow.css' import 'quill/dist/quill.bubble.css' import ImageResize from 'quill-image-resize-module' import * as Quill from 'quill' import { lineHeightStyle } from "./lineHeight"; var Size = Quill.import('attributors/style/size') Size.whitelist = ['10px', '12px', '14px', '16px', '18px', '20px', '30px', '32px', '38px', '48px', '64px'] // 引入編輯器 Quill.register(Size, true) Quill.register('modules/imageResize', ImageResize) const toolbarOptions = [ ['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' }], // 縮進 [{ size: Size.whitelist }], [{ 'align': [] }], [{ header: [1, 2, 3, 4, 5, 6, false] }], // 標題 [{ color: [] }, { background: [] }], // 字體顏色、字體背景顏色 ['clean'], // 清除文本格式 [{ lineHeight: lineHeightStyle.whitelist }], // 對齊方式 ['image'] // 鏈接、圖片 ] const toolbarTips = [ { Choice: '.ql-bold', title: '加粗' }, { Choice: '.ql-italic', title: '傾斜' }, { Choice: '.ql-underline', title: '下划線' }, { Choice: '.ql-header', title: '段落格式' }, { Choice: '.ql-strike', title: '刪除線' }, { Choice: '.ql-blockquote', title: '塊引用' }, { Choice: '.ql-code-block', title: '插入代碼段' }, { Choice: '.ql-size', title: '字體大小' }, { Choice: '.ql-list[value="ordered"]', title: '編號列表' }, { Choice: '.ql-list[value="bullet"]', title: '項目列表' }, { Choice: '.ql-header[value="1"]', title: 'h1' }, { Choice: '.ql-header[value="2"]', title: 'h2' }, { Choice: '.ql-align', title: '對齊方式' }, { Choice: '.ql-color', title: '字體顏色' }, { Choice: '.ql-background', title: '背景顏色' }, { Choice: '.ql-image', title: '圖像' }, { Choice: '.ql-video', title: '視頻' }, { Choice: '.ql-link', title: '添加鏈接' }, { Choice: '.ql-formula', title: '插入公式' }, { Choice: '.ql-clean', title: '清除格式' }, { Choice: '.ql-lineHeight', title: '設置行高' }, { Choice: '.ql-indent[value="-1"]', title: '向左縮進' }, { Choice: '.ql-indent[value="+1"]', title: '向右縮進' }, { Choice: '.ql-header .ql-picker-label', title: '標題大小' }, { Choice: '.ql-header .ql-picker-item[data-value="1"]', title: '標題一' }, { Choice: '.ql-header .ql-picker-item[data-value="2"]', title: '標題二' }, { Choice: '.ql-header .ql-picker-item[data-value="3"]', title: '標題三' }, { Choice: '.ql-header .ql-picker-item[data-value="4"]', title: '標題四' }, { Choice: '.ql-header .ql-picker-item[data-value="5"]', title: '標題五' }, { Choice: '.ql-header .ql-picker-item[data-value="6"]', title: '標題六' }, { Choice: '.ql-header .ql-picker-item:last-child', title: '標准' }, { Choice: '.ql-size .ql-picker-item[data-value="small"]', title: '小號' }, { Choice: '.ql-size .ql-picker-item[data-value="large"]', title: '大號' }, { Choice: '.ql-size .ql-picker-item[data-value="huge"]', title: '超大號' }, { Choice: '.ql-size .ql-picker-item:nth-child(2)', title: '標准' }, { Choice: '.ql-align .ql-picker-item:first-child', title: '居左對齊' }, { Choice: '.ql-align .ql-picker-item[data-value="center"]', title: '居中對齊' }, { Choice: '.ql-align .ql-picker-item[data-value="right"]', title: '居右對齊' }, { Choice: '.ql-align .ql-picker-item[data-value="justify"]', title: '兩端對齊' } ] export default { components: { quillEditor }, props: { /* 編輯器的內容 */ value: { type: String, default: () => {} }, /* 圖片大小 */ maxSize: { type: Number, default: 4000 // kb } }, data () { return { params: { token: '', FileName: '' }, content: this.value, quillUpdateImg: false, // 根據圖片上傳狀態來確定是否顯示loading動畫,剛開始是false,不顯示 editorOption: { placeholder: '您想說點什么?', theme: 'snow', // or 'bubble' modules: { imageResize: { displayStyles: { backgroundColor: 'black', border: 'none', color: 'white' }, modules: ['Resize', 'DisplaySize', 'Toolbar'] }, toolbar: { container: toolbarOptions, // container: "#toolbar", handlers: { image: function (value) { if (value) { // 觸發input框選擇圖片文件 document.querySelector('.avatar-uploader input').click() } else { this.quill.format('image', false) } }, lineHeight: (value) => { if (value) { const quill = this.$refs.myQuillEditor.quill quill.format("lineHeight", value); } } // link: function(value) { // if (value) { // var href = prompt('請輸入url'); // this.quill.format("link", href); // } else { // this.quill.format("link", false); // } // }, } } } }, serverUrl: this.UploadFile(), // 這里寫你要上傳的圖片服務器地址 header: { // token: sessionStorage.token } // 有的圖片服務器要求請求頭需要有token } }, watch: { value (val) { this.content = this.value } }, // computed: { // content () { // return this.value // } // }, mounted () { for (let item of toolbarTips) { let tip = document.querySelector('.quill-editor ' + item.Choice) if (!tip) continue tip.setAttribute('title', item.title) } }, created () { // this.$nextTick(() => { // document.getElementById('self_typt-add-container').scrollTop = 0 // }) }, methods: { ready() { Quill.register({ "formats/lineHeight": lineHeightStyle }, true) }, UploadFile () { return '/bmms/web-bm/file' }, onEditorBlur () { // 失去焦點事件 }, onEditorFocus (val) { // 獲得焦點事件 const quill = this.$refs.myQuillEditor.quill quill.format("lineHeight", 3); console.log('獲得焦點事件----',lineHeightStyle.whitelist) }, onEditorChange () { // 內容改變事件 this.content = this.content.replace(/href=/g, '') this.$emit('input', this.content) }, cuFocus () { this.$nextTick(function () { document.getElementById('self_typt-add-container').scrollTop = 0 }) }, httpRequest (param) { const form = new FormData() form.append('file', param.file, param.file.name) Uploads(form).then(res => { if (res.status === 200) { const quill = this.$refs.myQuillEditor.quill // 如果上傳成功 if (res.status === 200) { // 獲取光標所在位置 const length = quill.getSelection().index // 插入圖片 res.url為服務器返回的圖片地址 quill.insertEmbed(length, 'image', res.data.urlPath) // 調整光標到最后 quill.setSelection(length + 1) } else { this.$message.error('圖片插入失敗') } // loading動畫消失 this.quillUpdateImg = false } }) }, // 富文本圖片上傳前 beforeUpload (file) { // 顯示loading動畫 this.quillUpdateImg = true const filetype = file.name.slice( file.name.lastIndexOf('.'), file.name.length ) if (filetype === '.jpg' || filetype === '.png') { const isLt2M = file.size / 1024 / 1024 < 2 if (!isLt2M) { this.$message.error('上傳文件大小不能超過 2MB!') return false } else { return true } } else { this.$message.error('請上傳PNG,JPG格式文件') return false } }, handleChange (file, fileList) { var fileObj = file const form = new FormData() form.append('token', 'wnms') form.append('FileName', '44324') form.append('File', fileObj) } } } </script> <style lang="scss"> .ql-container{ >div:not(.ql-editor){ >div{ >span{ display: none !important; border:1px solid red !important; } } } } .editor { line-height: normal !important; height: 28rem; overflow: hidden; margin-top: -1vh; } .ql-container { overflow: auto; height: calc(100% - 50px); } .ql-editor { p{ img{ max-width: 100%; margin: auto ; display: block ; float: none !important; } } } .ql-snow .ql-editor,.ql-snow .ql-editor img { display: block; } .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-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-toolbar { white-space: normal; } .ql-picker-item[data-value='10px']::before, .ql-picker-label[data-value='10px']::before { content: '10px' !important; } .ql-picker-item[data-value='12px']::before, .ql-picker-label[data-value='12px']::before { content: '12px' !important; } .ql-picker-item[data-value='14px']::before, .ql-picker-label[data-value='14px']::before { content: '14px' !important; } .ql-picker-item[data-value='16px']::before, .ql-picker-label[data-value='16px']::before { content: '16px' !important; } .ql-picker-item[data-value='18px']::before, .ql-picker-label[data-value='18px']::before { content: '18px' !important; } .ql-picker-item[data-value='20px']::before, .ql-picker-label[data-value='20px']::before { content: '20px' !important; } .ql-picker-item[data-value='24px']::before, .ql-picker-label[data-value='24px']::before { content: '24px' !important; } .ql-picker-item[data-value='30px']::before, .ql-picker-label[data-value='30px']::before { content: '30px' !important; } .ql-picker-item[data-value='32px']::before, .ql-picker-label[data-value='32px']::before { content: '32px' !important; } .ql-picker-item[data-value='38px']::before, .ql-picker-label[data-value='38px']::before { content: '38px' !important; } .ql-picker-item[data-value='48px']::before, .ql-picker-label[data-value='48px']::before { content: '48px' !important; } .ql-picker-item[data-value='64px']::before, .ql-picker-label[data-value='64px']::before { content: '64px' !important; } .ql-picker-item[data-value='72px']::before, .ql-picker-label[data-value='72px']::before { content: '72px' !important; } .ql-picker-item[data-value='36px']::before, .ql-picker-label[data-value='36px']::before { content: '36px' !important; } .ql-editor .ql-indent-1:not(.ql-direction-rtl){ text-indent: 2em; padding-left: 0; } .ql-editor .ql-indent-2:not(.ql-direction-rtl){ text-indent: 4em; padding-left: 0; } .ql-editor .ql-indent-3:not(.ql-direction-rtl){ text-indent: 6em; padding-left: 0; } .ql-editor .ql-indent-4:not(.ql-direction-rtl){ text-indent: 8em; padding-left: 0; } .ql-editor .ql-indent-5:not(.ql-direction-rtl){ text-indent: 10em; padding-left: 0; } .ql-editor .ql-indent-6:not(.ql-direction-rtl){ text-indent: 12em; padding-left: 0; } .ql-editor .ql-indent-7:not(.ql-direction-rtl){ text-indent: 14em; padding-left: 0; } .ql-editor .ql-indent-8:not(.ql-direction-rtl){ text-indent: 16em; padding-left: 0; } .ql-snow .ql-picker.ql-lineHeight .ql-picker-label::before { content: "行高"; } .ql-snow .ql-picker.ql-lineHeight .ql-picker-item[data-value="1"]::before,.ql-snow .ql-picker.ql-lineHeight .ql-picker-label[data-value="1"]::before { content: "行高1"; } .ql-snow .ql-picker.ql-lineHeight .ql-picker-item[data-value="1.5"]::before, .ql-snow .ql-picker.ql-lineHeight .ql-picker-label[data-value="1.5"]::before { content: "行高1.5"; } .ql-snow .ql-picker.ql-lineHeight .ql-picker-item[data-value="1.75"]::before,.ql-snow .ql-picker.ql-lineHeight .ql-picker-label[data-value="1.75"]::before { content: "行高1.75"; } .ql-snow .ql-picker.ql-lineHeight .ql-picker-item[data-value="2"]::before,.ql-snow .ql-picker.ql-lineHeight .ql-picker-label[data-value="2"]::before { content: "行高2"; } .ql-snow .ql-picker.ql-lineHeight .ql-picker-item[data-value="3"]::before,.ql-snow .ql-picker.ql-lineHeight .ql-picker-label[data-value="3"]::before { content: "行高3"; } .ql-snow .ql-picker.ql-lineHeight .ql-picker-item[data-value="4"]::before,.ql-snow .ql-picker.ql-lineHeight .ql-picker-label[data-value="4"]::before { content: "行高4"; } .ql-snow .ql-picker.ql-lineHeight .ql-picker-item[data-value="5"]::before ,.ql-snow .ql-picker.ql-lineHeight .ql-picker-label[data-value="5"]::before{ content: "行高5"; } .ql-snow .ql-picker.ql-lineHeight { width: 70px; } </style>