富文本编辑器(vue-quill-editor)自定义工具栏按钮

安装
npm install vue-quill-editor --save
使用
1、引用

(1)局部引用,在使用页面引入

import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'

import { quillEditor } from 'vue-quill-editor'

export default {
  components: {
    quillEditor
  }
}

(2)全局引用,在main.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)
2、工具栏配置
  • toolbar为菜单工具栏,其中container为工具栏显示内容,每一个工具在页面上为一个按钮,handlers为按钮点击事件
  • 修改container控制工具栏的顺序和增删,其中insertMetric为自定义按钮
  • 在handlers中定义点击事件insertMetric: function (){}
editorOption: {
    modules: {
        toolbar: {
            container: [
                ['bold', 'italic', 'underline', 'strike'],
                ['blockquote'],
                [
                    {
                        header: 1
                    },
                    {
                        header: 2
                    }
                ],
                [
                    {
                        list: 'ordered'
                    },
                    {
                        list: 'bullet'
                    }
                ],
                [
                    {
                        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'],
                ['insertMetric'] //新添加的工具
            ],
            handlers: {
                shadeBox: null,
                insertMetric: function () {
                    //方法体
					alert(1);
                }
            }
        }
    }
},
content: '',  
3、页面元素
<quill-editor ref="editorComp" v-model="content" :options="editorOption"> </quill-editor>

//自定义按钮内容初始化
initButton() {
    const sourceEditorButton = document.querySelector('.ql-insertMetric');
    sourceEditorButton.innerHTML = '';
}

mounted() {
   this.initButton();
}

页面效果如图所示
富文本编辑器(vue-quill-editor)自定义工具栏按钮_第1张图片

此时,发现了一个问题,按钮很多,在不测试的情况下无法知道所有按钮的含义,于是增加按钮提示

4、增加工具栏提示
  • vue-quill-editor没有默认的设置,所以手动添加一个变量,循环工具栏的button,为其添加title属性

页面元素如下:
富文本编辑器(vue-quill-editor)自定义工具栏按钮_第2张图片

代码实现:

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-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-direction',
        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-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-font .ql-picker-label',
        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: '两端对齐'
    },
    {
        Choice: '.ql-insertMetric',
        title: '插入指标'
    }
]initButton() {
    document.getElementsByClassName('ql-editor')[0].dataset.placeholder = '';
    for (let item of this.toolbarTips) {
        let tip = document.querySelector('.quill-editor ' + item.Choice);
        if (!tip) continue;
        tip.setAttribute('title', item.title);
    }
},

mounted() {
   this.initButton();
}

实现效果:

富文本编辑器(vue-quill-editor)自定义工具栏按钮_第3张图片

5、自定义按钮方法
  • 在第三步中,定义了一个简单的按钮方法,此处,对方法内容进行详细描述

  • 自定义按钮在项目中的需求为:点击按钮,提示用户可以输入哪些信息,然后用户可以再这些信息上进行选择,并插入到页面元素,如图所示

富文本编辑器(vue-quill-editor)自定义工具栏按钮_第4张图片

(1) 页面元素,点击按钮时显示

  • append-to-body:Dialog 自身是否插入至 body 元素上。
  • 在嵌套Dialog场景中,将内层 Dialog 的该属性设置为 true,它就会插入至 body 元素上,从而保证内外层 Dialog 和遮罩层级关系的正确。只有一个弹窗可不必设置
<div v-if="showMetric">
    <el-dialog title="指标信息" :visible.sync="showMetric" width="600px" append-to-body>
        <el-table :data="variables" style="width: 100%">
            <el-table-column align="center" prop="name" label="时间" />
            <el-table-column align="center" prop="type" label="实例编号" />
            <el-table-column align="center" prop="ioType" label="命令" />
            <el-table-column align="center" prop="optional" label="命令" />
            <el-table-column align="center" prop="description" label="命令" />
            <el-table-column align="center" label="操作">
                <template slot-scope="scope">
<el-button @click="handleClick(scope.row)">插入el-button>
                template>
            el-table-column>
        el-table>
    el-dialog>
div>

(2)窗口显示方法

  • 注意:that: this 为自定义键值对,**insertMetric: function (){}**为匿名函数,匿名函数中this指向window,因此,自定义键值对,以便于在匿名函数内部可以获取到vue的this、
  • 点击按钮,showMetric = true,显示dialog
showMetric: false,
quill_this: this,
editorOption: {
	modules: {
		//省略其他内容
		handlers: {
            shadeBox: null,
            that: this,
            insertMetric: function () {
				//获取vue的this
                let self = this.handlers.that;
                self.showMetric = true;
				//获取window的this
                self.quill_this = this;
			}
		}
	}
},

(3)插入方法

  • 点击插入按钮,插入指标信息的name
import Delta from 'quill-delta';

handleClick(row) {
    this.insert(row.name);
    this.showMetric = false;
},

insert(name) {
	//获取editor实例
    let quill_this = this.quill_this;
	//editor自带方法:获取当前鼠标位置
    let range = quill_this.quill.getSelection(true);
	//插入内容
    let insert_value = '${' + name + '}';
	//editor自带方法:插入内容,更新页面元素,updateContents的第一个参数为Delta,需要引入
    quill_this.quill.updateContents(new Delta().retain(range.index).delete(range.length).insert(insert_value));
    quill_this.quill.setSelection(range.index + insert_value.length);
},
  • 插入方法参考工具栏中插入图片的方法,打印editor实例可见
    富文本编辑器(vue-quill-editor)自定义工具栏按钮_第5张图片
    富文本编辑器(vue-quill-editor)自定义工具栏按钮_第6张图片
完整代码
<template>
    <div>
        <el-card :style="contentHeight(120)">
            <quill-editor ref="editorComp" v-model="content" :options="editorOption"> quill-editor>
            <div v-if="showMetric">
                <el-dialog title="指标信息" :visible.sync="showMetric" width="600px" append-to-body>
                    <el-table :data="variables" style="width: 100%">
                        <el-table-column align="center" prop="name" label="时间" />
                        <el-table-column align="center" prop="type" label="实例编号" />
                        <el-table-column align="center" prop="ioType" label="命令" />
                        <el-table-column align="center" prop="optional" label="命令" />
                        <el-table-column align="center" prop="description" label="命令" />
                        <el-table-column align="center" label="操作">
                            <template slot-scope="scope">
                                <el-button @click="handleClick(scope.row)">插入el-button>
                            template>
                        el-table-column>
                    el-table>
                el-dialog>
            div>
        el-card>
    div>
template>

<script>
import { quillEditor } from 'vue-quill-editor';
import Delta from 'quill-delta';
import 'quill/dist/quill.core.css';
import 'quill/dist/quill.snow.css';
import 'quill/dist/quill.bubble.css';
import { deleteKey, deepClone } from '@/utils';
export default {
    name: 'editor',
    components: {
        quillEditor
    },
    data() {
        return {
            variables: [
                {
                    name: 'eventTime',
                    type: 'TIMEVAL',
                    ioType: 'OUT',
                    optional: false,
                    description: '事件时间'
                },
                {
                    name: 'begin',
                    type: 'TIMEVAL',
                    ioType: 'OUT',
                    optional: false,
                    description: '开始时间'
                },
                {
                    name: 'end',
                    type: 'TIMEVAL',
                    ioType: 'OUT',
                    optional: false,
                    description: '结束时间'
                },
                {
                    name: 'metricCode',
                    type: 'STRING',
                    ioType: 'OUT',
                    optional: false,
                    description: '指标代码'
                },
                {
                    name: 'metricName',
                    type: 'STRING',
                    ioType: 'OUT',
                    optional: false,
                    description: '指标名称'
                },
                {
                    name: 'metricValue',
                    type: 'STRING',
                    ioType: 'OUT',
                    optional: false,
                    description: '指标值'
                },
                {
                    name: 'ruleName',
                    type: 'STRING',
                    ioType: 'OUT',
                    optional: false,
                    description: '规则名称-事件标题'
                },
                {
                    name: 'port',
                    type: 'STRING',
                    ioType: 'IN',
                    optional: false,
                    description: '端口号'
                }
            ],
            editorOption: {
                modules: {
                    toolbar: {
                        container: [
                            ['bold', 'italic', 'underline', 'strike'],
                            ['blockquote'],
                            [
                                {
                                    header: 1
                                },
                                {
                                    header: 2
                                }
                            ],
                            [
                                {
                                    list: 'ordered'
                                },
                                {
                                    list: 'bullet'
                                }
                            ],
                            [
                                {
                                    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'],
                            ['insertMetric'] //新添加的工具
                        ],
                        handlers: {
                            shadeBox: null,
                            that: this,
                            insertMetric: function () {
                                let self = this.handlers.that;
                                self.showMetric = true;
                                self.quill_this = this;
                            }
                        }
                    }
                }
            },
            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-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-direction',
                    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-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-font .ql-picker-label',
                    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: '两端对齐'
                },
                {
                    Choice: '.ql-insertMetric',
                    title: '插入指标'
                }
            ],
            content: '',
            showMetric: false,
            quill_this: this,
        };
    },
    methods: {
        handleClick(row) {
            this.insert(row.name);
            this.showMetric = false;
        },
        initButton() {
            document.getElementsByClassName('ql-editor')[0].dataset.placeholder = '';
            for (let item of this.toolbarTips) {
                let tip = document.querySelector('.quill-editor ' + item.Choice);
                if (!tip) continue;
                tip.setAttribute('title', item.title);
            }
            const sourceEditorButton = document.querySelector('.ql-insertMetric');
            sourceEditorButton.innerHTML = '';
        },
        insert(name) {
            let quill_this = this.quill_this;
            console.log(quill_this);
            let range = quill_this.quill.getSelection(true);
            let insert_value = '${' + name + '}';
            quill_this.quill.updateContents(new Delta().retain(range.index).delete(range.length).insert(insert_value));
            quill_this.quill.setSelection(range.index + insert_value.length);
        },
    },
    mounted() {
        this.initButton();
    }
};
script>

你可能感兴趣的:(前端,#,vue,vue)