首先確保你的電腦有安裝node.js
本文基於vue、webpack、elementUi。
1.npm i vue-quill-editor --save
2.在main.js 中引入插件:
<template> <div> <!-- 圖片上傳組件輔助--> <el-upload class="avatar-uploader" :action="serverUrl" name="img" :headers="header" :show-file-list="false" :on-success="uploadSuccess" :on-error="uploadError" :before-upload="beforeUpload"> </el-upload> <quill-editor class="editor" v-model="content" ref="myQuillEditor" :options="editorOption" @blur="onEditorBlur($event)" @focus="onEditorFocus($event)" @change="onEditorChange($event)"> </quill-editor> </div> </template> <script> // 工具欄配置 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" }], // 縮進 // [{'direction': 'rtl'}], // 文本方向 [{ size: ["small", false, "large", "huge"] }], // 字體大小 [{ header: [1, 2, 3, 4, 5, 6, false] }], // 標題 [{ color: [] }, { background: [] }], // 字體顏色、字體背景顏色 [{ font: [] }], // 字體種類 [{ align: [] }], // 對齊方式 ["clean"], // 清除文本格式 //["link", "image","video"] // 鏈接、圖片、視頻 ["link", "image"] // 鏈接、圖片 ]; 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 { props: { /*編輯器的內容*/ value: { type: String }, /*圖片大小*/ maxSize: { type: Number, default: 4000 //kb } }, components: { quillEditor }, data() { return { content: this.value, quillUpdateImg: false, // 根據圖片上傳狀態來確定是否顯示loading動畫,剛開始是false,不顯示 editorOption: { placeholder: "", theme: "snow", // or 'bubble' placeholder: "您想說點什么?", modules: { toolbar: { container: toolbarOptions, // container: "#toolbar", handlers: { image: function(value) { if (value) { // 觸發input框選擇圖片文件 document.querySelector(".avatar-uploader input").click(); } else { this.quill.format("image", false); } }, // link: function(value) { // if (value) { // var href = prompt('請輸入url'); // this.quill.format("link", href); // } else { // this.quill.format("link", false); // } // }, } } } }, serverUrl: this.baseServerUrl+"/fileUpload/uploadPic?filepath=artwork", // 這里寫你要上傳的圖片服務器地址 header: { // token: sessionStorage.token } // 有的圖片服務器要求請求頭需要有token }; }, methods: { onEditorBlur() { //失去焦點事件 }, onEditorFocus() { //獲得焦點事件 }, onEditorChange() { //內容改變事件 this.$emit("input", this.content); }, // 富文本圖片上傳前 beforeUpload() { // 顯示loading動畫 this.quillUpdateImg = true; }, uploadSuccess(res, file) { console.log(res); console.log(file) // res為圖片服務器返回的數據 // 獲取富文本組件實例 let quill = this.$refs.myQuillEditor.quill; // 如果上傳成功 if (res.code == 1) { // 獲取光標所在位置 let length = quill.getSelection().index; // 插入圖片 res.url為服務器返回的圖片地址 quill.insertEmbed(length, "image", res.url); // 調整光標到最后 quill.setSelection(length + 1); } else { this.$message.error("圖片插入失敗"); } // loading動畫消失 this.quillUpdateImg = false; }, // 富文本圖片上傳失敗 uploadError() { // loading動畫消失 this.quillUpdateImg = false; this.$message.error("圖片插入失敗"); } } }; </script> <style> .editor { line-height: normal !important; width: 930px; margin: 0 auto; } .ql-container { height: 400px !important; } .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> <!-- 圖片上傳組件輔助--> <el-upload class="avatar-uploader" :action="serverUrl" name="img" :headers="header" :show-file-list="false" :on-success="uploadSuccess" :on-error="uploadError" :before-upload="beforeUpload"> </el-upload> <quill-editor class="editor" v-model="content" ref="myQuillEditor" :options="editorOption" @blur="onEditorBlur($event)" @focus="onEditorFocus($event)" @change="onEditorChange($event)"> </quill-editor> </div> </template> <script> // 工具欄配置 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" }], // 縮進 // [{'direction': 'rtl'}], // 文本方向 [{ size: ["small", false, "large", "huge"] }], // 字體大小 [{ header: [1, 2, 3, 4, 5, 6, false] }], // 標題 [{ color: [] }, { background: [] }], // 字體顏色、字體背景顏色 [{ font: [] }], // 字體種類 [{ align: [] }], // 對齊方式 ["clean"], // 清除文本格式 //["link", "image","video"] // 鏈接、圖片、視頻 ["link", "image"] // 鏈接、圖片 ]; 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 { props: { /*編輯器的內容*/ value: { type: String }, /*圖片大小*/ maxSize: { type: Number, default: 4000 //kb } }, components: { quillEditor }, data() { return { content: this.value, quillUpdateImg: false, // 根據圖片上傳狀態來確定是否顯示loading動畫,剛開始是false,不顯示 editorOption: { placeholder: "", theme: "snow", // or 'bubble' placeholder: "您想說點什么?", modules: { toolbar: { container: toolbarOptions, // container: "#toolbar", handlers: { image: function(value) { if (value) { // 觸發input框選擇圖片文件 document.querySelector(".avatar-uploader input").click(); } else { this.quill.format("image", false); } }, // link: function(value) { // if (value) { // var href = prompt('請輸入url'); // this.quill.format("link", href); // } else { // this.quill.format("link", false); // } // }, } } } }, serverUrl: this.baseServerUrl+"/fileUpload/uploadPic?filepath=artwork", // 這里寫你要上傳的圖片服務器地址 header: { // token: sessionStorage.token } // 有的圖片服務器要求請求頭需要有token }; }, methods: { onEditorBlur() { //失去焦點事件 }, onEditorFocus() { //獲得焦點事件 }, onEditorChange() { //內容改變事件 this.$emit("input", this.content); }, // 富文本圖片上傳前 beforeUpload() { // 顯示loading動畫 this.quillUpdateImg = true; }, uploadSuccess(res, file) { console.log(res); console.log(file) // res為圖片服務器返回的數據 // 獲取富文本組件實例 let quill = this.$refs.myQuillEditor.quill; // 如果上傳成功 if (res.code == 1) { // 獲取光標所在位置 let length = quill.getSelection().index; // 插入圖片 res.url為服務器返回的圖片地址 quill.insertEmbed(length, "image", res.url); // 調整光標到最后 quill.setSelection(length + 1); } else { this.$message.error("圖片插入失敗"); } // loading動畫消失 this.quillUpdateImg = false; }, // 富文本圖片上傳失敗 uploadError() { // loading動畫消失 this.quillUpdateImg = false; this.$message.error("圖片插入失敗"); } } }; </script> <style> .editor { line-height: normal !important; width: 930px; margin: 0 auto; } .ql-container { height: 400px !important; } .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>
3.在需要使用富文本的頁面中
html:
<Editor @input="handelIncrease"></Editor>
methods:
//接收父組件傳值
handelIncrease(step) {
console.log("step",step)
}
記得要引入組件:
import Editor from "@/components/Editor";
components: {
Editor
}
這樣就可以看到效果了:
