1.安装依赖npm install vue-quill-editor --save
2.使用
(1)引入
import { quillEditor } from "vue-quill-editor";
import { Quill } from "vue-quill-editor";
import "quill/dist/quill.core.css"; // import styles
import "quill/dist/quill.snow.css"; // for snow theme
import "quill/dist/quill.bubble.css"; //
import Upload from "@/components/plugins/upload";
//一定要引入这三个css,不然文本编辑器会变得奇奇怪怪的。
//可以在main.js中引入,也可以在具体使用的.vue文件中引入
//注册 Vue.use(quillEditor)或者components: {quillEditor}
(2)引用
图片或者视频的上传也可以使用自定义组件
工具栏toolbar的显示可以自定义
如果需要改变文本域部分的样式,如下:
.ql-toolbar {
&.ql-snow {
.ql-formats {
margin-right: 0;
}
.ql-picker {
height: 31px;
}
}
}
.link {
position: absolute;
bottom: 0;
right: 0;
width: 100%;
text-align: right;
padding-right: 10px;
i {
font-size: 20px;
}
}
.quill-editor {
line-height: normal;
height: 500px;
margin-bottom: 50px;
.ql-video {
video {
width: 100%;
}
}
}
完整的代码如下
<template>
<div>
<quill-editor
ref="quillEditor"
v-model="content"
@change="change"
@blur="blur"
:options="options"
/>
<div v-show="false">
<upload
ref="uploadRef"
:itemData="config"
:imgUrl="'legalPersonFront'"
@uploadSuccess="upload"
></upload>
</div>
</div>
</template>
<script>
import _ from "lodash";
import { quillEditor } from "vue-quill-editor";
import { Quill } from "vue-quill-editor";
import "quill/dist/quill.core.css"; // import styles
import "quill/dist/quill.snow.css"; // for snow theme
import "quill/dist/quill.bubble.css"; //
import Upload from "@/components/plugins/upload";
//引入修改过的video模块并注册
import Video from '../../../utils/video'
Quill.register(Video,true)
export default {
name: "forms",
components: {
quillEditor,
Upload
},
props: {
value: {
type: String,
default() {
return "";
}
},
defaultValue: {
type: String,
default() {
return "";
}
},
props: {
type: Object,
default() {
return {};
}
},
toolbarOptions: {
type: Array,
default() {
return [
['bold', 'italic', 'underline', 'strike'], // toggled buttons
['blockquote', 'code-block'],
[{ 'header': 1 }, { 'header': 2 }], // custom button values
[{ 'list': 'ordered'}, { 'list': 'bullet' }],
[{ 'script': 'sub'}, { 'script': 'super' }], // superscript/subscript
[{ 'indent': '-1'}, { 'indent': '+1' }], // outdent/indent
[{ 'direction': 'rtl' }], // text direction
[{ 'size': ['small', false, 'large', 'huge'] }], // custom dropdown
[{ 'header': [1, 2, 3, 4, 5, 6, false] }],
[{ 'color': [] }, { 'background': [] }], // dropdown with defaultfromtheme
[{ 'font': [] }],
[{ 'align': [] }],
['clean'],
['image'],
//工具栏
];
}
}
},
data() {
return {
config: {
label: "",
type: "source",
key: "corporateBankingCert",
colspan: 0,
width: 0,
height: 0
},
content: "",
isInit: false
// toolbarOpt: [["image", "video"], [{ align: [] }]]
};
},
watch: {
content() {
this.$emit("input", this.content);
},
value() {
if (!this.isInit) {
this.isInit = true;
this.content = this.value;
}
}
},
computed: {
options() {
return {
modules: {
toolbar: {
// container: , // 工具栏
container: this.toolbarOptions,
handlers: {
image: value => {
if (value) {
this.$refs.uploadRef.handleClick();
} else {
this.quill.format("image", false);
}
},
video: value => {
if (value) {
this.$refs.uploadRef.handleClick();
} else {
this.quill.format("video", false);
}
}
}
}
},
placeholder: "请输入",
theme: "snow", // or 'bubble',
...this.props
};
},
quill() {
const { quill } = this.$refs.quillEditor || {};
return quill;
}
},
created() {
this.isInit = false;
},
mounted() {
this.init();
},
methods: {
init() {
this.setSelection(this.content.length);
// this.blur();
if (!_.get(this.props, "autoHeight")) {
this.quill.root.style.height = `${_.get(this.props, "height", 300)}px`;
} else if (_.get(this.props, "minHeight")) {
this.quill.root.style.minHeight = `${_.get(
this.props,
"minHeight",
300
)}px`;
}
},
//失去焦点
blur() {
this.quill.enable(false);
this.$nextTick(() => {
if (this.quill) {
this.quill.enable(true);
this.quill.blur();
}
});
},
//获取焦点
focus() {
this.$nextTick(() => {
if (this.quill) {
this.quill.focus();
}
});
},
//光标位置
setSelection(index) {
this.$nextTick(() => {
let _index = index;
if (this.quill) {
if (!_.isNumber(index)) {
_index = this.getSelectionIndex() + 1;
}
this.quill.setSelection(_index);
}
});
},
getSelectionIndex() {
return _.get(this.quill.getSelection(), "index", 0);
},
change(option) {
this.$emit("change", option);
},
upload($event,type) {
let quill = this.quill;
// 如果上传成功
if ($event) {
// 获取光标所在位置
let index = this.getSelectionIndex();
// 根据返回类型,插入图片/视频,res为服务器返回的图片链接地址
if(type.includes("image")){
quill.insertEmbed(index, "image", $event);
}else if(type.includes("video")){
quill.insertEmbed(index, "video", $event);
}
// 调整光标到最后
this.setSelection();
} else {
// 提示信息,需引入Message
// Message.error('图片插入失败')
}
},
addLink() {
console.log("add");
}
}
};
</script>
<style lang="scss" scoped>
/deep/ .ql-toolbar {
&.ql-snow {
.ql-formats {
margin-right: 0;
}
.ql-picker {
height: 31px;
}
}
}
.link {
position: absolute;
bottom: 0;
right: 0;
width: 100%;
text-align: right;
padding-right: 10px;
i {
font-size: 20px;
}
}
.quill-editor {
line-height: normal;
height: 500px;
margin-bottom: 50px;
.ql-video {
video {
width: 100%;
}
}
}
</style>