vue-quill-editor富文本编辑器

由于我们在项目中使用的次数不会很多,这里将作为按需引入方式使用。

富文本编辑器-效果展示

安装依赖

npm install vue-quill-editor --save

创建 VueQuillEditor.js

import Vue from 'vue'
import VueQuillEditor from 'vue-quill-editor'
// require styles
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'
Vue.use(VueQuillEditor)

创建 titleConfig.js(可不添加)

// 文本提示语
export const titleConfig = {
    "ql-bold": "加粗" ,
    "ql-color": "颜色",
    "ql-font": "字体",
    "ql-code": "插入代码",
    "ql-italic": "斜体",
    "ql-link": "添加链接",
    "ql-background": "背景颜色",
    "ql-size": "字体大小",
    "ql-strike": "删除线",
    "ql-script": "上标/下标",
    "ql-underline": "下划线",
    "ql-blockquote": "引用",
    "ql-header": "标题",
    "ql-indent": "缩进",
    "ql-list": "列表",
    "ql-align": "文本对齐",
    "ql-direction": "文本方向",
    "ql-code-block": "代码块",
    "ql-formula": "公式",
    "ql-image": "图片",
    "ql-video": "视频",
    "ql-clean": "清除字体样式",
    "ql-upload": "文件"
};

按需引入方式

1.html

<el-upload
    v-show="false"
    class="upload-demo"
    :action="uploadImgUrl"
    :headers="uploadHeaders"
    accept="image/jpeg,image/png,image/bmp"
    :before-upload="handleBeforeUpload"
    :on-success="handleSuccess"
    :show-file-list="false"
>
    <el-button v-show="false" class="ivu-btn" size="small" type="primary"></el-button>
</el-upload>
<quill-editor class="ql-editor"
    v-model="content"
    ref="QuillEditor"
    :options="editorOption"
    @blur="onEditorBlur($event)"
    @focus="onEditorFocus($event)"
    @change="onEditorChange($event)"
></quill-editor>

2.javaSrcipt

import '@/assets/js/quillEditor/VueQuillEditor.js'
import { titleConfig } from '@/assets/js/quillEditor/titleConfig.js' // 富文本文本提示语
export default {
    data() {
        return {
            fileSize: 10,
            uploadHeaders: { // 图片上传接口请求头
                Authorization: "token",
                Platform: "web",
            },
            uploadImgUrl: "/upload", // 上传的图片服务器地址
            content: "",
            editorOption: {
                placeholder: '请在这里输入',
                modules: {
                    toolbar: {
                        container: [
                            ['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'],    //清除字体样式
                            ['image']    //上传图片
                            // ['image','video','link']    //上传图片、上传视频、上传文件
                        ],
                        handlers: {
                            'image': function (value) {
                                if (value) {
                                    // 调用iview图片上传
                                    document.querySelector('.upload-demo .ivu-btn').click()
                                } else {
                                    this.quill.format('image', false);
                                }
                            }
                        }
                    }
                }
            },
        }
    },
    // 在dom创建完成后再调用
    mounted() {
        // 富文本提示信息
        this.$nextTick(() => {
            const oToolBar = document.getElementsByClassName('ql-editor')[0];
            const aButton = oToolBar.querySelectorAll('button');
            const aSelect = oToolBar.querySelectorAll('select');
            aButton.forEach(function(item){
                if(item.className === 'ql-script'){
                    item.value === 'sub' ? item.title = '下标': item.title = '上标';
                }else if(item.className === 'ql-indent'){
                    item.value === '+1' ? item.title ='向右缩进': item.title ='向左缩进';
                }else{
                    item.title = titleConfig[item.classList[0]];
                }
            });
            aSelect.forEach(function(item){
                item.parentNode.title = titleConfig[item.classList[0]];
            });
        })
    },
    methods: {
        onEditorBlur(e){
            console.log(e, '失去焦点事件');
        },
        onEditorFocus(e){
            console.log(e, '获得焦点事件');
        },
        onEditorChange(e){
            console.log(e, '内容改变事件');
        },
        // 上传前校检格式和大小
        handleBeforeUpload(file) {
            // 检验文件类型
            const isIMAGE = (file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/bmp');
            if (!isIMAGE) {
                this.$message.error(`请上传图片类型文件!`);
                return false;
            }
            // 校检文件大小
            const isLt = file.size / 1024 / 1024 < this.fileSize;
            if (!isLt) {
                this.$message.error(`上传文件大小不能超过 ${this.fileSize} MB!`);
                return false;
            }
            return true;
        },
        handleSuccess (res) {
            // 获取富文本组件实例
            let quill = this.$refs.QuillEditor.quill
            // 如果上传成功
            if (res.code===0) {
                // 获取光标所在位置
                let length = quill.getSelection().index;
                // 插入图片,res为服务器返回的图片链接地址
                quill.insertEmbed(length, 'image', res.data)
                // 调整光标到最后
                quill.setSelection(length + 1)
            } else {
                // 提示信息,需引入Message
                this.$message.error('图片插入失败')
            }
        },
    }
}

编辑后成功返回

console.log(this.content);
解决图片上传后的 html 模板转码失败(看需求,非必须)
  • 【UrlEncode编码/UrlDecode解码】
encodeURIComponent(this.content); // 编码
decodeURIComponent(this.content); // 解码
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353

推荐阅读更多精彩内容