vue-quill-editor图片大小的编辑,拖拽,上传视频
- 在vue组件中注册和使用
<quill-editor v-model="formInline.viewConfig" :options="quillOption"></quill-editor>
- 在vue组件中引入配置文件
import quillConfig from '@/utils/quill-config'
- 配置文件如下:
/* 富文本编辑图片上传配置*/
// import { getToken } from '@/utils/auth' // get token from cookie
import * as Quill from "quill"; // 引入编辑器
import ImageResize from "quill-image-resize-module";
import {
ImageDrop
} from "quill-image-drop-module";
import {
Message
} from "element-ui";
import store from "@/store";
Quill.default.register("modules/imageDrop", ImageDrop);
Quill.default.register("modules/imageResize", ImageResize);
const url = process.env.VUE_APP_BASE_API;
const fonts = ["Microsoft-YaHei", "SimSun", "SimHei", "KaiTi", "FangSong", "Arial", "Times-New-Roman", "sans-serif"];
const Font = Quill.imports["formats/font"];
Font.whitelist = fonts; // 将字体加入到白名单
Quill.default.register(Font, true);
const sizesList = [false, "10px", "12px", "14px", "16px", "18px", "20px", "22px", "24px", "26px", "28px", "30px"];
const Size = Quill.imports["attributors/style/size"];
Size.whitelist = sizesList;
Quill.default.register(Size, true);
const uploadConfigImg = {
action: url + "/upload/up", // 必填参数 图片上传地址
methods: "POST", // 必填参数 图片上传方式
token: sessionStorage.getItem("token"), // 可选参数 如果需要token验证,假设你的token有存放在sessionStorage
name: "upfile", // 必填参数 文件的参数名
size: 5242880, // 可选参数 图片大小,单位为字节。1兆字节(mb)=1048576字节(b)
accept: "image/png, image/gif, image/jpeg, image/bmp, image/x-icon" // 可选 可上传的图片格式
};
const uploadConfigVideo = {
action: url + "/upload/up", // 必填参数 视频上传地址
methods: "POST", // 必填参数 视频上传方式
token: sessionStorage.getItem("token"), // 可选参数 如果需要token验证,假设你的token有存放在sessionStorage
name: "upfile", // 必填参数 文件的参数名
size: 209715200, // 可选参数 视频大小,单位为字节。1兆字节(mb)=1048576字节(b)
accept: "audio/mp4, video/mp4, video/mpeg" // 可选 可上传的视频格式
};
let pathHeader = ""
if (process.env.NODE_ENV === "development") {
pathHeader = "http://192.168.7.28:91"
}
// toolbar工具栏的工具选项(默认展示全部)
const toolOptions = [
["bold", "italic", "underline"], // strike
// ['blockquote', 'code-block'],
// [{ 'header': 1 }, { 'header': 2 }],
// [{ 'list': 'ordered' }, { 'list': 'bullet' }],
// [{ 'script': 'sub' }, { 'script': 'super' }],
// [{ 'indent': '-1' }, { 'indent': '+1' }],
// [{ 'direction': 'rtl' }],
// [{ 'size': ['small', false, 'large', 'huge'] }],
[{
"header": [1, 2, 3, 4, 5, 6, false]
}],
[{
"color": []
}, {
"background": []
}],
[{
"font": fonts
}],
[{
"size": sizesList
}],
[{
"align": []
}],
// ['clean'],
["image", "video"] // link
];
const handlers = {
image: function image() {
var self = this;
// var fileInputImg = this.container.querySelector('input.ql-image[type=file]')
var fileInputImg = null;
// console.log('fileInputImg', fileInputImg)
if (fileInputImg === null) {
fileInputImg = document.createElement("input");
fileInputImg.setAttribute("type", "file");
// 设置图片参数名
if (uploadConfigImg.name) {
fileInputImg.setAttribute("name", uploadConfigImg.name);
}
// 可设置上传图片的格式
fileInputImg.setAttribute("accept", uploadConfigImg.accept);
fileInputImg.classList.add("ql-image");
// 监听选择文件
fileInputImg.addEventListener("change", function () {
// 限制图片大小
if (uploadConfigImg.size && fileInputImg.files[0].size >= uploadConfigImg.size) {
Message.warning("图片大小不能超过5M");
fileInputImg.value = "";
return;
}
// 创建formData
var formData = new FormData();
formData.append(uploadConfigImg.name, fileInputImg.files[0]);
formData.append("object", "product");
// 如果需要token且存在token
if (uploadConfigImg.token) {
formData.append("token", uploadConfigImg.token);
}
// 图片上传
var xhr = new XMLHttpRequest();
xhr.open(uploadConfigImg.methods, uploadConfigImg.action, true);
xhr.setRequestHeader("Authorization", sessionStorage.getItem("token"));
// 上传数据成功,会触发
xhr.onload = function (e) {
if (xhr.status === 200) {
var res = JSON.parse(xhr.responseText);
const length = self.quill.getSelection(true).index;
// 这里很重要,你图片上传成功后,img的src需要在这里添加,res.path就是你服务器返回的图片链接。
self.quill.insertEmbed(length, "image", pathHeader + res.data.path);
self.quill.setSelection(length + 1);
}
fileInputImg.value = "";
};
// 开始上传数据
xhr.upload.onloadstart = function (e) {
fileInputImg.value = "";
};
// 当发生网络异常的时候会触发,如果上传数据的过程还未结束
xhr.upload.onerror = function (e) {};
// 上传数据完成(成功或者失败)时会触发
xhr.upload.onloadend = function (e) {
// console.log('上传结束')
};
xhr.send(formData);
});
this.container.appendChild(fileInputImg);
}
fileInputImg.click();
},
video: function video() {
var self = this;
var fileInputVideo = null;
if (fileInputVideo === null) {
fileInputVideo = document.createElement("input");
fileInputVideo.setAttribute("type", "file");
// 设置图片参数名
if (uploadConfigVideo.name) {
fileInputVideo.setAttribute("name", uploadConfigVideo.name);
}
// 可设置上传图片的格式
fileInputVideo.setAttribute("accept", uploadConfigVideo.accept);
fileInputVideo.classList.add("ql-image");
// 监听选择文件
fileInputVideo.addEventListener("change", function () {
// 限制图片大小
if (uploadConfigVideo.size && fileInputVideo.files[0].size >= uploadConfigVideo.size) {
Message.warning("视频大小不能超过200M");
fileInputVideo.value = "";
return;
}
// 创建formData
var formData = new FormData();
formData.append(uploadConfigVideo.name, fileInputVideo.files[0]);
formData.append("object", "product");
// 如果需要token且存在token
if (uploadConfigVideo.token) {
formData.append("token", uploadConfigVideo.token);
}
// 图片上传
var xhr = new XMLHttpRequest();
xhr.open(uploadConfigVideo.methods, uploadConfigVideo.action, true);
xhr.setRequestHeader("Authorization", sessionStorage.getItem("token"));
// 上传数据成功,会触发
xhr.onload = function (e) {
if (xhr.status === 200) {
var res = JSON.parse(xhr.responseText);
const length = self.quill.getSelection(true).index;
// 这里很重要,你图片上传成功后,img的src需要在这里添加,res.path就是你服务器返回的图片链接。
self.quill.insertEmbed(length, "video", pathHeader + res.data.path);
self.quill.setSelection(length + 1);
}
fileInputVideo.value = "";
};
// 开始上传数据
xhr.upload.onloadstart = function (e) {
fileInputVideo.value = "";
};
// 当发生网络异常的时候会触发,如果上传数据的过程还未结束
xhr.upload.onerror = function (e) {};
// 上传数据完成(成功或者失败)时会触发
xhr.upload.onloadend = function (e) {
// console.log('上传结束')
};
xhr.send(formData);
});
this.container.appendChild(fileInputVideo);
}
fileInputVideo.click();
}
};
export default {
placeholder: "",
theme: "snow", // 主题
modules: {
imageResize: {},
imageDrop: true,
toolbar: {
container: toolOptions, // 工具栏选项
handlers: handlers // 事件重写
}
// toolbar: '#toolbar'
}
};
- 在app.vue中引入字体样式.css文件。
<template>
<div id="app">
<router-view />
</div>
</template>
<script>
export default {
name: "App"
};
</script>
<style>
@import "./styles/quill-editor.css";
</style>
- 字体样式的css:
.ql-snow .ql-picker.ql-size,
.ql-snow .ql-picker.ql-header {
width: 75px !important;
}
.ql-snow .ql-picker.ql-font {
width: 80px !important;
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="10px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="10px"]::before {
content: "10px";
font-size: 10px;
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="12px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="12px"]::before {
content: "12px";
font-size: 12px;
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="14px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="14px"]::before {
content: "14px";
font-size: 14px;
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="16px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="16px"]::before {
content: "16px";
font-size: 16px;
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="18px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="18px"]::before {
content: "18px";
font-size: 18px;
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="20px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="20px"]::before {
content: "20px";
font-size: 20px;
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="22px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="22px"]::before {
content: "22px";
font-size: 22px;
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="24px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="24px"]::before {
content: "24px";
font-size: 24px;
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="26px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="26px"]::before {
content: "26px";
font-size: 26px;
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="28px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="28px"]::before {
content: "28px";
font-size: 28px;
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="30px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="30px"]::before {
content: "30px";
font-size: 30px;
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="SimSun"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="SimSun"]::before {
content: "宋体";
font-family: "SimSun";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="SimHei"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="SimHei"]::before {
content: "黑体";
font-family: "SimHei";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="Microsoft-YaHei"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="Microsoft-YaHei"]::before {
content: "微软雅黑";
font-family: "Microsoft YaHei";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="KaiTi"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="KaiTi"]::before {
content: "楷体";
font-family: "KaiTi";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="FangSong"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="FangSong"]::before {
content: "仿宋";
font-family: "FangSong";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="Arial"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="Arial"]::before {
content: "Arial";
font-family: "Arial";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Times-New-Roman]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Times-New-Roman]::before {
content: "Times New Roman";
font-family: "Times New Roman";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=sans-serif]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=sans-serif]::before {
content: "sans-serif";
font-family: "sans-serif";
}
.ql-font-SimSun {
font-family: "SimSun";
}
.ql-font-SimHei {
font-family: "SimHei";
}
.ql-font-Microsoft-YaHei {
font-family: "Microsoft YaHei";
}
.ql-font-KaiTi {
font-family: "KaiTi";
}
.ql-font-FangSong {
font-family: "FangSong";
}
.ql-font-Arial {
font-family: "Arial";
}
/* .ql-font-Times-New-Roman {
font-family: "Times New Roman";
}
.ql-font-sans-serif {
font-family: "sans-serif";
} */
最后,这里有两个问题要注意一下:
一、引入ImageResize 和 ImageDrop 模块报错,需要在webpack中安装一个Quill插件。
- 如果你的项目是vue-cli3创建的,在vue.conf.js(如果没有这个文件,就手动在项目根目录和src同级,创建vue.conf.js),加上下面的配置:
const webpack = require('webpack')
module.exports = {
chainWebpack: config => {
config.plugin('provide').use(webpack.ProvidePlugin, [{
'window.Quill': 'quill'
}])
}
- 如果你的项目是vue-cli2创建的项目,那么可以使用这个方法:在build/webpack.base.conf.js添加, 然后配置下面的代码:
var webpack = require('webpack');
module: {
rules: [
{
test: /.js$/,
exclude: /node_modules(?!/quill-image-drop-module|quill-image-resize-module)/,
loader: 'babel-loader',
query: {...}
}
]
}
plugins: [
new webpack.ProvidePlugin({
'window.Quill': 'quill'
})
]
二、在需要展示图片的地方,也需要安装vue-quill-edit,并且引入样式,才能展示图片改变后的大小。