前言
使用vue-quill-editor中的一个收获
一、一些相关的文档
通过在这些文档中的阅读,应该可以了解了怎么使用,如果想要在项目中自定使用,那就需要download下来跑一跑了
二、在项目使用
1、安装 vue-quill-editor
首先需要在你的终端执行下面的命令
npm install vue-quill-editor —-save
2、组件的使用
1)这里是局部引用。
import { quillEditor, Quill } from 'vue-quill-editor';
// require styles
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'
需要在局部引入样式,否则样式不生效
import { quillEditor, Quill } from 'vue-quill-editor';
export default {
components: {
quillEditor
}
}
需要在你的components中注册一下。
2)这里是全局引用。
import Vue from 'vue'
import QuillEditor 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(QuillEditor)
在 main.js 中将 vue-quill-editor 引入项目。
详细的配置请参考 Quill 官网
3)在vue中的使用
这里以全局引入为例
// editor 组件
<template>
<div>
<!-- bidirectional data binding(双向数据绑定) -->
<!-- 全局引入组建名称 必须为quill-editor -->
<!-- style 样式是合并空格的作用,在editor中对多个连续空格换行处理,根据需求进行添加/删除 -->
<quill-editor
style="white-space: pre-line; word-wrap: break-word"
:disabled="disabled"
v-model="content"
ref="myQuillEditor"
:options="editorOption"
@blur="onEditorBlur($event)"
@focus="onEditorFocus($event)"
@change="onEditorChange($event)"
@input="handleModel"
>
<div :id="`toolbar${editorKey}`" :slot="'toolbar'">
<el-button
:disabled="disabled"
class="ql-custom-button"
size="small"
@click="openDialog"
>
打开弹框
</el-button>
</div>
</QuillEditor>
<el-dialog
title="提示"
:visible.sync="dialogVisible"
width="30%"
:before-close="handleClose"
>
<span>这是一段信息</span>
<el-button @click="insert('插入第一名称')">插入第一名称</el-button>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button
type="primary"
@click="dialogVisible = false"
>
确 定
</el-button>
</span>
</el-dialog>
</div>
</template>
maxlength 限制最大输入字数,通过compositionstart,compositionend 事件对拼音输入文字超长时特殊处理
// editor 组件
<script>
export default {
model: {
prop: "modelValue",
event: "update:modelValue",
},
props: {
modelValue: {
type: String,
required: true,
default() {
return "";
},
},
editorKey: {
type: String,
},
disabled: {
type: Boolean,
},
maxlength: {
type: Number,
default: 0
}
},
computed: {
editor() {
return this.$refs.myQuillEditor.quill;
},
editorOption() {
return {
placeholder: "请输入",
modules: {
toolbar: `#toolbar${this.editorKey}`,
},
};
},
},
watch: {
modelValue(val) {
this.content = val;
},
},
data() {
return {
content: this.modelValue,
// 编辑器焦点位置
quillIndex: 0,
// 编辑器选中的长度
quillLength: '',
// 编辑器选中的文本
quillSelectionText: "",
// 动态参数
params: [],
// 内容字符总长
count: 0,
dialogVisible: false,
composing: false,
};
},
mounted() {
// 获取 Quill 实例
const editor = this.editor;
if (editor) {
// 通过 Quill 的 root 元素来添加事件监听
editor.root.addEventListener('compositionstart', this.onCompositionStart);
editor.root.addEventListener('compositionend', this.onCompositionEnd);
}
},
methods: {
// 失去焦点事件
onEditorBlur() {
if (!this.disabled) {
// do something
}
},
// 获得焦点事件
onEditorFocus($event) {
if ($event) {
let { index, length } = $event.getSelection();
this.quillIndex = index;
this.quillLength = length || 0;
}
},
// 内容改变事件
onEditorChange({ quill, html, text }) {
// 光标插入失去焦点前的位置
if (text) {
if (this.editor.getSelection()) {
this.quillIndex = this.editor.getSelection().index;
} else {
// 末尾有一个\n字符
this.quillIndex = text && (text.length - 1);
this.quillLength = 0;
}
}
if ((text.length > this.maxlength) && !this.composing) {
let ExceedsLength = text.length - this.maxlength;
this.editor.deleteText(this.maxlength, ExceedsLength);
}
this.$emit("onEditorChange", text);
},
handleModel(e) {
this.$emit("update:modelValue", e);
},
openDialog(type) {
this.dialogVisible = true;
},
// 根据光标位置插入内容;有选中内容,删除后替换;
insert(param) {
if (this.editor.getSelection()) {
let { index, length } = this.editor.getSelection();
if (length) {
this.editor.deleteText(index, length);
} else {
}
this.editor.insertText(this.quillIndex, param);
} else {
if (this.quillLength) {
let index = this.quillIndex;
this.editor.deleteText(this.quillIndex, this.quillLength);
this.editor.insertText(index, param);
} else {
this.editor.insertText(this.quillIndex, param);
}
}
this.$emit("onEditorChange", this.editor.getText());
},
handleClose(done) {
this.$confirm("确认关闭?")
.then((_) => {
done();
})
.catch((_) => {});
},
onCompositionStart(val) {
this.composing = true;
},
onCompositionEnd(val) {
this.composing = false;
if ((this.maxlength && (this.editor.getText().length > this.maxlength))) {
let ExceedsLength = this.editor.getText().length - this.maxlength;
this.editor.deleteText(this.maxlength, ExceedsLength);
}
}
},
};
</script>
可以结合element ui 中el-form使用,校验时用el-form-item的rules进行校验
// 父组件
<div v-for="(value, key) in editorList" :key="key">
<editor
:editorKey="key"
v-model="value.html"
@onEditorChange="
editorChange(
$event,
value,
key
)
"
:maxlength="20"
></editor>
</div>
在父组件中循环使用
// 父组件
data() {
return {
editorList: {
1: {
html: "",
content: "",
},
2: {
html: "",
content: "",
}
},
};
},
methods: {
// 保存纯文本内容
editorChange(content, value, key) {
this.$set(value, "content", content);
// this.$refs.formDataRef.validateField([
// `card_content.${key}.html`,
// ]);
},
}
好啦,本文到此结束,感谢您的阅读!
如果你觉得这篇文章有需要修改完善的地方,欢迎在评论区留下你宝贵的意见或者建议
如果你觉得这篇文章还不错的话,欢迎点赞、收藏、关注,你的支持是对我最大的鼓励 (/ω\)