富文本编辑器(vue-quill-editor)自定义工具栏按钮
vue
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
项目地址:https://gitcode.com/gh_mirrors/vu/vue
免费下载资源
·
安装
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 = '<i class="el-icon-plus" style="font-size: 18px;color: black"></i>';
}
mounted() {
this.initButton();
}
页面效果如图所示
此时,发现了一个问题,按钮很多,在不测试的情况下无法知道所有按钮的含义,于是增加按钮提示
4、增加工具栏提示
- vue-quill-editor没有默认的设置,所以手动添加一个变量,循环工具栏的button,为其添加title属性
页面元素如下:
代码实现:
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();
}
实现效果:
5、自定义按钮方法
-
在第三步中,定义了一个简单的按钮方法,此处,对方法内容进行详细描述
-
自定义按钮在项目中的需求为:点击按钮,提示用户可以输入哪些信息,然后用户可以再这些信息上进行选择,并插入到页面元素,如图所示
(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实例可见
完整代码
<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 = '<i class="el-icon-plus" style="font-size: 18px; color: black"></i>';
},
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>
GitHub 加速计划 / vu / vue
207.54 K
33.66 K
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:2 个月前 )
73486cb5
* chore: fix link broken
Signed-off-by: snoppy <michaleli@foxmail.com>
* Update packages/template-compiler/README.md [skip ci]
---------
Signed-off-by: snoppy <michaleli@foxmail.com>
Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 4 个月前
e428d891
Updated Browser Compatibility reference. The previous currently returns HTTP 404. 5 个月前
更多推荐
已为社区贡献1条内容
所有评论(0)