Vue wangEditor介绍及使用说明和其他富文本编辑器
wangEditor是一个轻量级 web 富文本编辑器,配置方便,使用简单。
官方文档:https://www.wangeditor.com/
本文介绍vue如何使用wangEditor,进行这些操作(编辑富文本内容/显示内容/上传图片/删除图片)。后台数据库中保存的富文本就是html,顺便把图片的地址一并保存在里面。
安装
npm安装wangEditor: npm install wangEditor
单个Vue页面使用
<template>
<div>
<!--编辑区域-->
<div ref="editor" v-html="textEditor"></div>
<!--显示区域,一定要用样式-->
<pre class="sd_pre_change_note" style="overflow-y: scroll;" v-html="textDescription"></pre>
</div>
</template>
<script>
import wangEditor from 'wangeditor' // 引入 wangEditor
export default {
name: 'JustTest',
data (){
textEditor:'',
textDescription:'',
editor:null, //wangEditor编辑器
imgsrc: [],
},
created () {
this.createEditor()
},
destroyed() {
this.editor.destroy()
this.editor = null
},
methods: {
//创建富文本编辑器
createEditor(){
let that = this
const editor = new wangEditor(this.$refs.editor) //创建编辑器
editor.config.height = 370 // 设置编辑区域高度为 500px
editor.config.excludeMenus = [ // 配置菜单栏,设置不需要的菜单
'todo',
'video'
],
editor.config.showLinkImg = false //隐藏插入网络图片的功能
//文本内容发生变换
editor.config.onchange = (newHtml) => {
this.onContentchange(newHtml)
this.textDescription = newHtml
}
//上传文件
editor.config.uploadImgServer = 'http://127.0.0.1:8000/backend/upload'
editor.config.uploadImgMaxSize = 2 * 1024 * 1024 // 2M
editor.config.uploadImgAccept = ['jpg', 'jpeg', 'png']
editor.config.uploadImgMaxLength = 3 // 一次最多上传 3 个图片
editor.config.uploadImgParams = {
updir: 'detail',
}
editor.config.uploadFileName = 'image'
editor.config.uploadImgHooks = {
before: function(xhr) { // 上传图片之前
// 可阻止图片上传
// return {
// prevent: true,
// msg: '需要提示给用户的错误信息'
// }
},
success: function(xhr) { // 图片上传并返回了结果,图片插入已成功
console.log('success', xhr)
},
fail: function(xhr, editor, resData) { // 图片上传并返回了结果,但图片插入时出错了
this.$message({type: 'error', message: '插入图片失败!'})
console.log('fail', resData)
},
error: function(xhr, editor, resData) { // 上传图片出错,一般为 http 请求的错误
this.$message({type: 'error', message: '上传图片失败!'})
console.log('error', xhr, resData)
},
timeout: function(xhr) { // 上传图片超时
this.$message({type: 'error', message: '上传图片超时!'})
console.log('timeout')
},
// 图片上传并返回了结果,想要自己把图片插入到编辑器中
// 例如服务器端返回的不是 { errno: 0, data: [...] } 这种格式,可使用 customInsert
customInsert: function(insertImgFn, result) {
// result 即服务端返回的接口
// insertImgFn 可把图片插入到编辑器,传入图片 src ,执行函数即可
insertImgFn(result.data[0])
that.imgsrc = that.getSrc(editor.txt.html()) //获取富文本中包含的所有图片地址
}
}
editor.create()
this.editor = editor
},
// html 即变化之后的内容, 删除图片
onContentchange(html){
if (this.imgsrc.length !== 0) {
let nowimgs = this.getSrc(html)
let merge = this.imgsrc.concat(nowimgs).filter(function (v, i, arr) {
return arr.indexOf(v) === arr.lastIndexOf(v)
})
//后台请求,删除图片
let params = {imgPaths:JSON.stringify(merge)}
this.axios.post(`/auditInfo/deleteImg`,qs.stringify(params))
.then(response =>{
console.log(response.data);
})
.catch(function (error) {
console.log(error);
});
this.imgsrc = nowimgs
}
},
//得到html中的图片地址
getSrc (html) {
var imgReg = /<img.*?(?:>|\/>)/gi
// 匹配src属性
var srcReg = /src=[\\"]?([^\\"]*)[\\"]?/i
var arr = html.match(imgReg)
let imgs = []
if (arr) {
for (let i = 0; i < arr.length; i++) {
var src = arr[i].match(srcReg)[1]
imgs.push(src)
}
}
return imgs
},
}
}
</script>
<style scoped lang="less">
/*wangEditor css*/
/deep/.sd_pre_change_note{
table {
border-top: 1px solid #ccc;
border-left: 1px solid #ccc;
}
table td, table th {
border-bottom: 1px solid #ccc;
border-right: 1px solid #ccc;
padding: 3px 5px;
}
table th {
background-color: #f1f1f1;
border-bottom: 2px solid #ccc;
text-align: center;
}
/* blockquote 样式 */
blockquote {
display: block;
border-left: 8px solid #d0e5f2;
padding: 5px 10px;
margin: 10px 0;
line-height: 1.4;
font-size: 100%;
background-color: #f1f1f1;
}
/* code 样式 */
code {
display: inline-block;
*display: inline;
*zoom: 1;
background-color: #f1f1f1;
border-radius: 3px;
padding: 3px 5px;
margin: 0 3px;
}
pre code {
display: inline-flex;
}
/* ul ol 样式 */
ul, ol {
margin: 10px 0 10px 20px;
}
</style>
后台部分 urls.py
from django.conf.urls import url
from django.urls import path
from Apps.AuditList import auditList as auditListViews
urlpatterns = [
...
path('auditInfo/deleteImg', auditListViews.deleteImg, name='deleteImg'),
path('backend/upload', auditListViews.uploadImags, name='uploadImags'),
url(r'^auditImg/(?P<path>.*)$', serve, {'document_root': os.path.join(BASE_DIR, "static/img/detail"),}), #显示静态资源 图片
...
]
views.py
from django.http import JsonResponse, HttpResponse
import os
import re
import json
def deleteImg(request):
if request.method == 'POST':
response = {}
try:
imgPaths = json.loads(request.POST.get('imgPaths','[]'))
for i in imgPaths:
matchData = re.search(r'auditImg/(.*)', i)
if matchData:
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
file_path = BASE_DIR + '/static/img/detail/'+matchData.groups()[0] #拼出server上保存的图片路径
os.remove(file_path)
response['msg'] = 'success'
response['error_num'] = 0
except Exception as e:
print(traceback.format_exc(limit=1))
response['msg'] = str(e)
response['error_num'] = 1
return JsonResponse(response)
#audit富文本 上传图片 图片保存在/static/img/detail/下
def uploadImags(request):
if request.method == 'POST':
resp = {'errno': 100, 'data': '请选择图片'}
upfiles = request.FILES.getlist('image', None)
updir = request.POST.get('updir', 'common')
if(upfiles == None):
return HttpResponse(json.dumps(resp), content_type="application/json")
resUrls = []
resIds = []
for up in upfiles:
upfileres = _upload(up, updir)
resUrls.append(upfileres['url'])
resIds.append(upfileres['id'])
#前端使用的plopload上传,一次上传一张,多张分多次上传, 使用的wangeditor,是多张图片是一次上传的
if updir == 'detail':
resp = {'errno': 0, 'data': resUrls}
else:
resp = {'errno': 200, 'id': resIds[0], 'url': resUrls[0]}
return HttpResponse(json.dumps(resp), content_type="application/json")
def _upload(upfile, updir):
new_file_name = _hash_filename(upfile.name)
res_save_path = _get_path(updir)
save_path = res_save_path['save_path']
local_save_path = res_save_path['local_save_path']
local_save_file = local_save_path + new_file_name
save_file = save_path + new_file_name
url = 'http://127.0.0.1:8000/' + save_file.replace('static/img/'+updir,'auditImg')
with open(local_save_file, 'wb') as f:
for line in upfile.chunks():
f.write(line)
f.close()
return {'id': 23, 'url': url}
def _hash_filename(filename):
_, suffix = os.path.splitext(filename)
return '%s%s' % (uuid.uuid4().hex, suffix)
def _get_path(updir):
if(updir == ''):
path = 'static/img/' + time.strftime("%Y%m%d", time.localtime()) + '/'
else:
path = 'static/img/' + updir + '/' + time.strftime("%Y%m%d", time.localtime()) + '/'
# 本地储存路径
local_save_path = path
# 数据库存储路径
save_path = os.path.join(path)
isExists = os.path.exists(local_save_path)
if not isExists:
os.makedirs(local_save_path)
return {'save_path': save_path, 'local_save_path': local_save_path}
1.富文本插入表情,保存html到后台失败
要使用富文本的表情图,需要设置该字段的格式为utf8mb4
ALTER TABLE auditinfo MODIFY testDescription TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
SHOW FULL COLUMNS FROM auditinfo;
2.插入图片成功了,但是还是要实现删除图片的功能,防止服务器保存无用的信息,删除图片的功能,成功添加.
3.wangEditor图片上传
1.图片上传
var E = window.wangEditor
var editor = new E('#editorMenu','#editor')
//开启debug模式
editor.customConfig.debug = true;
// 关闭粘贴内容中的样式
editor.customConfig.pasteFilterStyle = false
// 忽略粘贴内容中的图片
editor.customConfig.pasteIgnoreImg = true
// 使用 base64 保存图片
//editor.customConfig.uploadImgShowBase64 = true
// 上传图片到服务器
editor.customConfig.uploadFileName = 'myFile'; //设置文件上传的参数名称
editor.customConfig.uploadImgServer = 'upload'; //设置上传文件的服务器路径
editor.customConfig.uploadImgMaxSize = 10 * 1024 * 1024; // 将图片大小限制为 3M
editor.customConfig.uploadImgMaxLength = 5;
editor.customConfig.uploadImgHooks = {
success: function (xhr, editor, result) {
// 图片上传并返回结果,图片插入成功之后触发
// xhr 是 XMLHttpRequst 对象,editor 是编辑器对象,result 是服务器端返回的结果
},
fail: function (xhr, editor, result) {
// 图片上传并返回结果,但图片插入错误时触发
// xhr 是 XMLHttpRequst 对象,editor 是编辑器对象,result 是服务器端返回的结果
},
error: function (xhr, editor) {
// 图片上传出错时触发
// xhr 是 XMLHttpRequst 对象,editor 是编辑器对象
}
}
后台代码
@Data
public class WangEditor {
private Integer errno; //错误代码,0 表示没有错误。
private String[] data; //已上传的图片路径
public WangEditor(String[] data) {
super();
this.errno = 0;
this.data = data;
}
}
@RequestMapping(value = "/upload",method=RequestMethod.POST)
@ResponseBody
public WangEditor uploadFile(
@RequestParam("myFile") MultipartFile multipartFile,
HttpServletRequest request) {
try {
// 获取项目路径
String realPath = request.getSession().getServletContext()
.getRealPath("");
InputStream inputStream = multipartFile.getInputStream();
String contextPath = request.getServletContext().getContextPath();
// 服务器根目录的路径
String path = realPath.replace(contextPath.substring(1),"");
// 根目录下新建文件夹upload,存放上传图片
String uploadPath = path + "upload";
// 获取文件名称
String filename = Calendar.getInstance().getTimeInMillis()+"image";
// 将文件上传的服务器根目录下的upload文件夹
File file = new File(uploadPath, filename);
FileUtils.copyInputStreamToFile(inputStream, file);
// 返回图片访问路径
String url = request.getScheme() + "://" + request.getServerName()
+ ":" + request.getServerPort() + "/upload/" + filename;
String [] strs = {url};
WangEditor we = new WangEditor(strs);
return we;
} catch (IOException e) {
logger.error("上传文件失败", e);
}
return null;
}
2.多图片上传
editor.customConfig.customUploadImg = function (files, insert) {
var data= new FormData();
for(var i=0;i<files.length;i++){
data.append("files",files[i]);
}
$.ajax({
url:basePath + 'uploadFile/wangEditUploadImag',
type: "POST",
data: data,
success:function(da){
if(da.errno == 0){
for(var j=0;j<da.data.length;j++){
insert(da.data[j]);
}
}else{
alert(da.msg);
return;
}
}
});
}
@RequestMapping(value = "/upload1",method=RequestMethod.POST)
@ResponseBody
public WangEditor uploadFile(
@RequestParam("files") MultipartFile[] files,
HttpServletRequest request) {
try {
List list = new ArrayList();
for(MultipartFile multipartFile:files) {
// 获取项目路径
String realPath = request.getSession().getServletContext()
.getRealPath("");
InputStream inputStream = multipartFile.getInputStream();
//String contextPath = request.getServletContext().getContextPath();
//logger.info(contextPath);
// 服务器根目录的路径
String path = realPath;
// 根目录下新建文件夹upload,存放上传图片
String uploadPath = path + "upload";
// 获取文件名称
String filename = Calendar.getInstance().getTimeInMillis()+"image";
// 将文件上传的服务器根目录下的upload文件夹
File file = new File(uploadPath, filename);
FileUtils.copyInputStreamToFile(inputStream, file);
// 返回图片访问路径
String url = request.getScheme() + "://" + request.getServerName()
+ ":" + request.getServerPort() + "/upload/" + filename;
list.add(url);
}
//ArrayList<String> list=new ArrayList<String>();
String[] strings = new String[list.size()];
list.toArray(strings);
WangEditor we = new WangEditor(strings);
return we;
} catch (IOException e) {
logger.error("上传文件失败", e);
}
return null;
}
其他富文本编辑器:
TinyMCE
:这是一个非常流行的富文本编辑器,广泛用于网页内容的编辑。它提供了丰富的插件和主题,可以高度定制以满足不同用户的需求。
CKEditor
:另一个广泛使用的富文本编辑器,以其稳定性和强大的功能而闻名。CKEditor提供了所见即所得的编辑体验,并且支持各种文件格式的导入和导出。
UEditor
:这是一个由百度团队开发的富文本编辑器,支持多种语言,具有丰富的功能和良好的兼容性。
MarkitUp
:一个轻量级的、可定制的jQuery富文本编辑器,适用于CMS、博客、论坛等。
jwYSIWYG
:一个简单的jQuery所见即所得编辑器,提供了基本的文字编辑和图片链接功能。
Lightweight RTE
:一个非常轻量级的jQuery富文本编辑器,只提供基本的文字格式化功能。
HTMLBox
:一个跨浏览器的开源jQuery富文本编辑器,具有很好的交互性和用户手册,便于集成。
AiEditor
:一个面向AI的下一代富文本编辑器,支持全框架,并且对Markdown友好。
Textbus
:一个以组件为中心,数据驱动的富文本编辑器开发框架,旨在解决传统富文本开发中遇到的问题。
更多推荐
所有评论(0)