tips:操作按钮必须用img标签
使用方法
<q-editor ref="editor" :content="content"></q-editor>
取值
this.$refs.editor.getContent()
源码
// 富文本编辑器
Vue.component('q-editor', {
data() {
return {
operationList: [
{title: '加粗', exec: 'bold'},
{title: '斜体', exec: 'italic'},
{title: '下划线', exec: 'underline'},
{title: '删除线', exec: 'strikeThrough'},
{title: '居左', exec: 'justifyLeft'},
{title: '居中', exec: 'justifyCenter'},
{title: '居右', exec: 'justifyRight'},
{title: '图片', exec: 'insertImage'}
],
fileInput: null
}
},
props: {
content: {
type: String,
default: '<p><br></p>'
},
},
template: `
<div class="q_editor">
<div class="q_ed_operation">
<template v-for="(d, index) in operationList" :key="index">
<a :key="index" @click="setExecCommand(d)">
<img :src="'/image/q-editor/'+d.exec+'.png'" alt="">
</a>
</template>
</div>
<div class="q_ed_content" ref="q_ed_content" contentEditable="true" @paste.prevent="stick" @keydown.enter.prevent="preventEnter($event)" v-html="content"></div>
</div>
`,
mounted() {
// 初始化文本内容
if (this.content.length < 1) {
this.$refs.q_ed_content.innerHTML = '<p><br></p>'
}
document.execCommand('styleWithCSS', false, true);
},
methods: {
//屏蔽默认回车,插入换行符
preventEnter() {
document.execCommand('insertHTML', false, `<p><br></p>`)
},
// 粘贴板清空样式
stick(e) {
e.preventDefault();
var text;
var clp = (e.originalEvent || e).clipboardData;
if (clp === undefined || clp === null) {
text = window.clipboardData.getData("text") || "";
if (text !== "") {
if (window.getSelection) {
var newNode = document.createElement("span");
newNode.innerHTML = text;
window.getSelection().getRangeAt(0).insertNode(newNode);
} else {
document.selection.createRange().pasteHTML(text);
}
}
} else {
text = clp.getData('text/plain') || "";
if (text !== "") {
document.execCommand('insertText', false, text);
}
}
},
// execCommand 设置基础样式
setExecCommand(item) {
const _this = this;
// 光标移入编辑框
this.$refs.q_ed_content.focus();
if (item.exec === 'insertImage') {
// 创建上传控件
this.fileInput = document.createElement("input");
this.fileInput.type = 'file';
this.fileInput.name = 'name';
this.fileInput.accept = 'image/gif,image/jpeg,image/jpg,image/png';
this.fileInput.click();
this.fileInput.onchange = function () {
var file = _this.fileInput.files[0];
var formData = new FormData();
formData.append("", file);
formData.append("img_type", 3);
var xhr = new XMLHttpRequest();
xhr.open("post", "/uploadImg");
xhr.send(formData);
xhr.onload = function () {
var xhrData = JSON.parse(xhr.response);
if (xhrData.error_code == 0) {
// 插入图片
document.execCommand('insertImage', false, xhrData.result);
} else {
console.log('上传图片失败')
}
// 销毁上传控件
_this.fileInput = null
};
}
} else {
this.execOperation(item.exec)
}
},
//最终执行函数
execOperation(name) {
// 获取当前选区
let selection = window.getSelection();
let getRange = selection.getRangeAt(0);
if (!getRange.toString()) {
return false
}
let bool = document.execCommand(name);
getRange.detach();
return bool
},
//规划html标签
getContent() {
const ele = this.$refs.q_ed_content;
let innerHTML = ele.innerHTML;
// 图片垂直居中
if (innerHTML.indexOf('<img src=') > -1) {
innerHTML = innerHTML.replace(/<img src=/g, '<img style="vertical-align: middle;" src=');
}
return innerHTML
}
}
});