Vue-Quill-Editor 富文本编辑器和 Element-ui 的安装和使用各大博客论坛已经有很多,这里不再赘述。
图片上传:
Vue-Quill-Editor 上传图片默认转换成base64的形式,存储在数据库里会很长,于是使用文件上传服务器的路径来存储。
<quill-editor
v-model="content"
ref="myQuillEditor"
class="ql-editor-class"
:options="editorOption"
>
</quill-editor>
<el-upload
style="display: none" //隐藏
class="quill-picture-uploader" //类名,不能重复
action="http://localhost:8080/project/uploadPic" //后台上传接口
:before-upload="bfUpload" //上传之前调用
:on-success="uploadSuccess" //上传成功调用
:headers="myHeaders" //token,非必要
>
</el-upload>
data() {
return {
//图片url
urlList: [],
//正文
content: "",
//富文本配置
editorOption: {
placeholder: "正文内容支持上传图片和视频",
theme: "snow",
modules: {
toolbar: {
container: toolbarOptions, //自定义工具栏,略
handlers: {
image: function (value) { //替换原图片上传功能
if (value) {
document.querySelector(".quill-picture-uploader input").click(); //核心
} else {
this.quill.format("image", false);
}
},
}
},
},
},
};
},
F12查看一个 element-upload 组件可以看到它的结构是这样的。querySelector() 方法返回文档中匹配指定 CSS 选择器的一个元素,具体用法可以百度了解。这句代码的意思就是触发指定类名元素下,input元素的点击事件,达到点击编辑器里的图片上传按钮,却触发 element-upload 上传方法的效果。
//上传图片之前校验
bfUpload(file) {
console.log(file)
if ("image/png" == file.type || "image/jpeg" == file.type) {
} else {
this.$message.error('图片插入失败,请检查文件格式');
return;
}
},
//正文插入图片上传成功调用
uploadSuccess(response, file, fileList) {
this.urlList.push(response.url);
let quill = this.$refs.myQuillEditor.quill;
if (response.url != null) {
//获取光标所在位置
let length = quill.getSelection().index;
//插入图片
quill.insertEmbed(length, 'image', response.url);
//移动光标到图片后
quill.setSelection(length + 1);
}
},
效果图:
视频上传:
Vue-Quill-Editor 上传视频时输入对应的URL,会转换成 iframe 标签存储,所以不必更改默认设置,只需提供一个视频上传接口(如果需要实现点击直接上传效果,参考图片上传)。代码参考:https://www.cnblogs.com/1312mn/p/11233395.html
<el-dialog
title="视频上传"
:visible.sync="dialogVideoVisible"
width="40%"
:close-on-click-modal="false"
>
<myVideo></myVideo> //封装的组件
</el-dialog>
<template>
<el-row :gutter="20">
<el-col :span="24">
<div class="videoArea">
<el-upload
class="avatar-uploader"
action="http://localhost:8080/project/uploadVideo"
:headers="myHeaders"
:before-upload="beforeUploadVideo"
:on-success="handleVideoSuccess"
:on-progress="uploadVideoProcess"
:show-file-list="false"
>
<video
v-if="videoForm.showVideoPath != '' && !videoFlag"
:src="videoForm.showVideoPath"
controls
width="400"
height="240"
>
您的浏览器不支持视频播放
</video>
<i
v-else-if="videoForm.showVideoPath == '' && !videoFlag"
class="el-icon-plus avatar-uploader-icon"
></i>
<!-- 进度条 -->
<el-progress
v-if="videoFlag == true"
type="circle"
:percentage="videoUploadPercent"
style="margin-top: 7px"
></el-progress>
</el-upload>
</div>
</el-col>
<el-col :span="24">
<div class="textArea">
<p>
<span>单次最多上传1个视频,大小不要超过50M,上传后返回的URL用于正文插入视频</span>
</p>
<p>
<span v-if="videoForm.showVideoPath != ''">视频URL:
<span class="urlArea">
{{ videoForm.showVideoPath }}
</span>
</span>
</p>
</div>
</el-col>
</el-row>
</template>
<script>
export default {
data() {
return {
//token
myHeaders: { Authorization: localStorage.getItem("token") },
//视频
videoFlag: false,
//是否显示进度条
videoUploadPercent: "",
//进度条的进度,
isShowUploadVideo: false,
//显示上传按钮
videoForm: {
showVideoPath: "",
},
};
},
methods: {
//上传前回调
beforeUploadVideo(file) {
var fileSize = file.size / 1024 / 1024 < 50;
if (
[
"video/mp4",
"video/ogg",
"video/flv",
"video/avi",
"video/wmv",
"video/rmvb",
"video/mov",
].indexOf(file.type) == -1
) {
this.$message.error("请上传正确的视频格式");
return false;
}
if (!fileSize) {
this.$message.error("视频大小不能超过50MB");
return false;
}
this.isShowUploadVideo = false;
},
//进度条
uploadVideoProcess(event, file, fileList) {
this.videoFlag = true;
this.videoUploadPercent = file.percentage.toFixed(0) * 1;
},
//上传成功回调
handleVideoSuccess(res, file) {
this.isShowUploadVideo = true;
this.videoFlag = false;
this.videoUploadPercent = 0;
if (200 == res.code) {
this.videoForm.showVideoPath = res.url;
} else {
this.$message.error(res.msg);
}
},
},
};
效果图: