富文本
vue-quill-editor
需要下载vue-quill-editor模块,引入css和js
npm i vue-quill-editor
import "quill/dist/quill.core.css";
import "quill/dist/quill.snow.css";
import "quill/dist/quill.bubble.css";
import {quillEditor} from "vue-quill-editor";
v-model="detailContent"
ref="myQuillEditor"
:options="editorOption"
@blur="onEditorBlur($event)"
@focus="onEditorFocus($event)"
@ready="onEditorReady($event)"
>
//绑定的富文本内容
class="avatar-uploader"
:action="serverUrl"
name="img"
:headers="header"
:show-file-list="false"
:on-success="uploadSuccess"
:on-error="uploadError"
:before-upload="beforeUpload"
>
//elmentui 的插件
/因为input file类型的特殊原因这里用elmentui 的插件来唤起上传图片 在beforeUpload钩子函数里传递file
复制代码
###上传回调
beforeUpload(e) {
this.fileChanges(e);
}
复制代码
上传七牛代码
//qiniu 此对象需要 引入七牛
fileChanges(e) {
var _t = this;
let url = 'uploadxxx'
var ext = e.type.split("/")[1];
var formData = new FormData();
formData.append("ext", ext);
$.ajax({
type: "get",
async: false,
url: url,
data: {
ext: ext,
},
dataType: "json",
xhrFields: {
withCredentials: true
},
success: function(data) {
if (data.code === 0) {
var config = {
useCdnDomain: true,
region: qiniu.region.z1
};
var observable = qiniu.upload(
e,
data.info.keys[0],
data.info.token,
null,
config
);
_t.subscription = observable.subscribe({
next(res) {},
error(err) {
// ...
},
complete(res) {
// ...
let quill = _t.editor;
// 如果上传成功
// 获取光标所在位置
let length = quill.getSelection().index;
// 插入图片 res.info为服务器返回的图片地址
let str = quill.insertEmbed(
length,
"image",
data.info.bucketUrl + data.info.keys
);
// 调整光标到最后
quill.setSelection(length + 1);
}
});
}
},
error: function(e) {
}
});
}
复制代码
数据格式整理
上传完了富文本结构可能是这样,图片地址显示base64 是预览,等到上传完成返回就会替换成服务器地址,因为最近接口有问题,所以显示的地址有问题,可以忽略。
这时候移动端没有富文本,移动端和pc都要显示这段内容,这时候就要统一格式了。要把上面的html解构转换为json格式,这里就要用到html2json了,他可以吧dom节点转换为父子级节点的json,使用起来很方便,如果自己去转换会有很多问题。至于转换的原理我想应该是递归查询节点,在生成树结构。没有认真去看码哈哈。
移动端需要的格式
newsRichText: "[{"state":"textasdasd"},{"state":"imaghttps://post-static.maimaicc.com/post-static/2019-05-16/1570005744/WXLrk0c-0.jpeg"}]"
复制代码
转码列子
npm install html2json
var html2json = require('html2json').html2json;
var json2html = require('html2json').json2html;
API
json === html2json(document.body.innerHTML);
html === json2html(json);
console.assert(json === html);
复制代码
html
sample text with inline tag
foo
goo
复制代码
json
{
node: 'root',
child: [
{
node: 'element',
tag: 'div',
attr: { id: '1', class: 'foo' },
child: [
{
node: 'element',
tag: 'h2',
child: [
{ node: 'text', text: 'sample text with ' },
{ node: 'element', tag: 'code', child: [{ node: 'text', text: 'inline tag' }] }
]
},
{
node: 'element',
tag: 'pre',
attr: { id: 'demo', class: ['foo', 'bar'] },
child: [{ node: 'text', text: 'foo' }]
},
{
node: 'element',
tag: 'pre',
attr: { id: 'output', class: 'goo' },
child: [{ node: 'text', text: 'goo' }]
},
{
node: 'element',
tag: 'input',
attr: { id: 'execute', type: 'button', value: 'execute' }
}
]
}
]
}
复制代码
转换
//对插件生成的数据进行处理,处理成自己想要的格式 "[{"state":"textasdasd"},{"state":"imaghttps://xxxx.jpeg"}]"
release(types, bol = true) {
let json = html2json(this.detailContent);
let arr = [];
for (let i of json.child) {
for (let j of i.child) {
if (j.node == "text") {
let obj = {};
let tex = "text" + j.text;
obj.state = tex;
arr.push(obj);
} else if (j.tag == "img") {
let obj = {};
let tex = "imag" + j.attr.src;
obj.state = tex;
arr.push(obj);
}
}
}
复制代码var html2json = require("html2json").html2json;
复制代码
这样就完成了用elmentui在富文本中上传图片,并且将富文本转换为移动端可显示的内容,理论上后台应该保存两份格式的代码,一份是转换后的用于移动端读取,一份用来pc端显示,这样才能保证富文本的格式不变,样式不会出问题。所以需要两个字段,一个用于pc端读取,一个用于移动端读取。
感觉都是很棒的插件省了很多力气,尤其是这个富文本组件和转换格式插件,都很棒用起来,富文本是我用过最简单省力的富文本编辑器,强烈推荐。