vue-quill-editor 富文本图片、视频上传设置

news/2024/11/23 3:55:28/
<template><div class="card" style="overflow: hidden; padding-bottom: 10px"><div class="box"><div><div class="box_count"><div class="box_l"><FlexLinePI :title="'图文标题'" :dropshow="true"><el-inputv-model="ruleForm.title"maxlength="50"type="text"placeholder="请输入标题"></el-input></FlexLinePI><FlexLinePI :title="'图文摘要'" :dropshow="true"><el-inputv-model="ruleForm.note"type="textarea"maxlength="200"show-word-limitrows="5"placeholder="请输入正文详情"></el-input></FlexLinePI><FlexLinePI :title="'封面图片'" :dropshow="true"><el-uploadclass="avatar-uploader":action="upload":show-file-list="false":on-success="handleAvatarSuccess":before-upload="beforeAvatarUpload"><imgv-if="ruleForm.cover":src="ruleForm.cover"class="avatar"/><i v-else class="el-icon-plus avatar-uploader-icon"></i><div slot="tip" class="el-upload__tip">建议上传图片尺寸800*800px,大小不超过5M</div></el-upload></FlexLinePI><FlexLinePI :title="''" :dropshow="false"><div><div class="rich-uploader"><!-- 图片上传组件辅助--><el-uploadclass="rich-uploader2"name="pic"action="":show-file-list="false":http-request="httpRequest"></el-upload><el-uploadclass="rich-uploader3"name="pic"action="":show-file-list="false":http-request="httpRequestvideo"></el-upload></div><quill-editorv-model="ruleForm.content"ref="quillEditor":options="editorOption"></quill-editor></div></FlexLinePI><div class="buttom"><el-button type="primary" @click="addandedit(0)">保存</el-button><el-button type="primary" @click="addandedit(1)">保存并发布</el-button><!-- <el-button type="primary" @click="look">预览</el-button> --></div></div><divclass="box_r":style="{'background-image': `url(${require('../../../assets/images/phone.png')}`,}"><div class="box_r_informationurl"><div class="box_r_inImg"><imgsrc="../../../assets/images/authorlogo.png"alt=""srcset=""style="width: 100%; height: 100%"/></div><div class="box_r_inlanguage"><pstyle="-webkit-line-clamp: 1; font-size: 18px"class="ellipsis">{{ ruleForm.title != "" ? ruleForm.title : "请输入标题" }}</p><div style="display: flex; margin-top: 5px; height: 90px"><div style="flex: 1; -webkit-line-clamp: 5" class="ellipsis">{{ ruleForm.note != "" ? ruleForm.note : "请输入正文详情" }}</div><div class="box_r_inlanguageimg"><img:src="ruleForm.cover != '' ? ruleForm.cover : urlimg"alt=""srcset=""style="width: 100%; height: 100%"/></div></div></div></div></div></div></div></div></div>
</template>
<script>
import step from "@/components/EchartsChart/nextstep.vue";
import { upload, uploadvideo } from "@/api/common.js";
import { quillEditor, Quill } from "vue-quill-editor";
import "quill/dist/quill.core.css";
import "quill/dist/quill.snow.css";
import "quill/dist/quill.bubble.css";
import axios from "axios";
import {detailGraphic,addGraphic,updateGraphic,
} from "@/api/material/index.js";
// 引入修改video模块并注册
import video from "@/assets/js/quillVideo.js";
Quill.register(video);
export default {name: "AddImageText",components: { quillEditor, step },computed: {quill() {const { quill } =  this.$refs.quillEditor || {} return quill;},},data() {const toolbarOptions = [["bold", "italic", "underline", "strike"], //加粗,斜体,下划线,删除线["blockquote", "code-block"], //引用,代码块[{ header: 1 }, { header: 2 }], // 标题,键值对的形式;1、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: [] }], //字体[{ align: [] }], //对齐方式["clean"], //清除字体样式["image"], //上传图片["video"], // 视频];return {upload: upload,uploadvideo: uploadvideo,ruleForm: {id: "",title: "",note: "",cover: "",content: "",},// 视频progress: 0,// 富文本editorOption: {placeholder: "请输入内容",theme: "snow",modules: {toolbar: {container: toolbarOptions, // 工具栏handlers: {image: function (value) {if (value) {console.log(value);// 触发input框选择图片文件document.querySelector(".rich-uploader2 input").click();} else {this.quill.format("image", false);}},video: function (value) {if (value) {console.log(value);// 触发input框选择图片文件document.querySelector(".rich-uploader3 input").click();} else {this.quill.format("video", false);}},},},},},// 上传图片urlimg: require("../../../assets/images/gift.png"),// 当前idupdateId: sessionStorage.getItem("updateId")? sessionStorage.getItem("updateId"): "",};},mounted() {if (this.updateId == "" || this.updateId == null) {this.ruleForm = {id: "",title: "",note: "",cover: "",content: "",};} else {// 详情this.getdetail(this.updateId);}},computed: {},methods: {//handleAvatarSuccess(res, file) {if (res.status == 1) {this.ruleForm.cover = res.data.real_path;}},beforeAvatarUpload(file) {const isLt2M = file.size / 1024 / 1024 < 5;if (!isLt2M) {this.$message.error("上传头像图片大小不能超过 5MB!");}return isLt2M;},// 详情getdetail(id) {detailGraphic({id: id,}).then((res) => {if (res.status == 1) {this.ruleForm = {id: res.data.id,title: res.data.title,note: res.data.note,cover: res.data.cover,content: res.data.content,};} else {this.$message.warning(res.msg || "数据响应过慢,请稍后再试");}}).catch((err) => {console.log(err);});},//  步骤 2 =====================================================httpRequest(item) {let quill = this.$refs.quillEditor.quill;let formdata = new FormData();formdata.append("file", item.file, item.file.name);formdata.append("type", "1");let length = quill.getSelection().index;quill.insertEmbed(length, "image", item.file);axios.post(upload, formdata, {header: { "Content-Type": "multipart/form-data" },}).then((res) => {if (res.data.status == 1) {let length = quill.getSelection().index;// 插入图片  服务器返回的图片地址quill.insertEmbed(length, "image", res.data.data.real_path);//       // 调整光标到最后quill.setSelection(length + 1);} else {this.$message.warning(res.msg || "数据响应过慢,请稍后再试");}}).catch((err) => {console.log(err);});},// ==============================================================// 保存编辑addandedit(val) {if (this.updateId == "" || this.updateId == null) {let tmpParams = {id: "",title: this.ruleForm.title, // 时间note: this.ruleForm.note, // 时间cover: this.ruleForm.cover,content: this.ruleForm.content,is_publish: val,};this.sever(tmpParams);} else {let tmpParams = {id: this.updateId,title: this.ruleForm.title, // 时间note: this.ruleForm.note, // 时间cover: this.ruleForm.cover,content: this.ruleForm.content,is_publish: val,};this.edit(tmpParams);}},// 保存sever(val) {addGraphic(val).then((res) => {if (res.status == 1) {this.dialogVisible = false;this.$router.push({name: "ImageText",});} else {this.$message.warning(res.msg || "数据响应过慢,请稍后再试");}}).catch((err) => {console.log(err);});},// 编辑edit(val) {updateGraphic(val).then((res) => {if (res.status == 1) {this.dialogVisible = false;this.$router.push({name: "ImageText",});} else {this.$message.warning(res.msg || "数据响应过慢,请稍后再试");}}).catch((err) => {console.log(err);});},// 视频上传 =================httpRequestvideo(item) {let chunkSize = 1024 * 1024 * 5; // 每个切片的大小(这里设置为1MB)let totalChunks = Math.ceil(item.file.size / chunkSize); // 总切片数let currentChunk = 1; // 当前切片索引const uploadNextChunk = () => {const formData = new FormData();formData.append("name", item.file.name);formData.append("data", item.file);formData.append("total", totalChunks);formData.append("index", currentChunk);formData.append("filename", item.file.name);axios.post(uploadvideo + "?act=upload", formData, {headers: { "Content-Type": "multipart/form-data" },onUploadProgress: (progressEvent) => {this.progress = Math.round((currentChunk * 100 +progressEvent.loaded / progressEvent.total) /totalChunks);},}).then((res) => {currentChunk++;if (currentChunk < totalChunks + 1) {uploadNextChunk();} else {this.progress = 0; // 上传完成后重置进度let date = {name: item.file.name,data: item.file,total: totalChunks,index: currentChunk,filename: item.file.name,};this.uploadok(date);}}).catch((error) => {console.error("Error uploading file:", error);});};uploadNextChunk();},uploadok(val) {let quill = this.$refs.quillEditor.quill;let formdata = new FormData();formdata.append("name", val.name);formdata.append("data", val.data);formdata.append("total", val.total);formdata.append("index", val.index);formdata.append("filename", val.filename);// let length = quill.getSelection().index;// quill.insertEmbed(length, "video", val.data);axios.post(uploadvideo + "?act=join", formdata, {headers: { "Content-Type": "multipart/form-data" },}).then((res) => {if (res.data.status == 1) {let length = quill.getSelection().index;// 插入图片  服务器返回的图片地址quill.insertEmbed(length, "video", res.data.path);// 调整光标到最后quill.setSelection(length + 1);} else {this.$message.warning(res.msg || "数据响应过慢,请稍后再试");}}).catch((error) => {console.error("Error uploading file:", error);});},},
};
</script>
<style scoped lang='less'>
p {margin: 0;padding: 0;
}
.box {width: 90%;margin: 0 auto;padding: 10px 0;.box_count {display: flex;// justify-content: center;.box_l {width: 50%;}.box_r {width: 320px;height: 580px;margin: 10px 10px 10px 100px;background-size: 100% 100%;// box-shadow: 0 0 10px 0 #ccc;border-radius: 25px;position: relative;.box_r_informationurl {width: 100%;margin-top: 60px;display: flex;padding: 30px;.box_r_inImg {width: 50px;height: 50px;margin-left: 10px;}.box_r_inlanguage {flex: 1;margin: 0 10px;background: #ffffff;padding: 10px;border-radius: 5px;.box_r_inlanguageimg {width: 50px;height: 50px;}}}}}.buttom {display: flex;justify-content: center;margin: 10px 0;}
}
/deep/ .ql-container {height: 600px;
}
/deep/ .avatar {border-radius: 0;
}
</style>
// 文件主要是使视频video替换ifrom标签的文档进行使用import { Quill } from "vue-quill-editor";
// 源码中是import直接倒入,这里要用Quill.import引入
const BlockEmbed = Quill.import("blots/block/embed");
const Link = Quill.import("formats/link");const ATTRIBUTES = ["height", "width"];class Video extends BlockEmbed {static create(value) {const node = super.create(value);// 添加video标签所需的属性node.setAttribute("controls", "controls");node.setAttribute("type", "video/mp4");node.setAttribute("src", this.sanitize(value));return node;}static formats(domNode) {return ATTRIBUTES.reduce((formats, attribute) => {if (domNode.hasAttribute(attribute)) {formats[attribute] = domNode.getAttribute(attribute);}return formats;}, {});}static sanitize(url) {return Link.sanitize(url);}static value(domNode) {return domNode.getAttribute("src");}format(name, value) {if (ATTRIBUTES.indexOf(name) > -1) {if (value) {this.domNode.setAttribute(name, value);} else {this.domNode.removeAttribute(name);}} else {super.format(name, value);}}html() {const { video } = this.value();return `<a href="${video}">${video}</a>`;}
}
Video.blotName = "video"; // 这里不用改,楼主不用iframe,直接替换掉原来,如果需要也可以保留原来的,这里用个新的blot
Video.className = "ql-video";
Video.tagName = "video"; // 用video标签替换iframeexport default Video;

http://www.ppmy.cn/news/82079.html

相关文章

Linux 防火墙 SNAT DNAT

SNAT原理与应用 SNAT 应用环境 局域网主机共享单个公网IP地址接入Internet &#xff08;私有IP地址不能在Internet中正常路由&#xff09; SNAT原理 修改数据包的源地址 SNAT可以认为是路由器NAT中的easy ip DNAT可以认为是路由器NAT中的 nat server SNAT将 内网源地址 转化为网…

19-02 基于业务量级的架构技术选型演进

从零开始——单服务应用 单体应用技术选型 &#xff08;GitHub、Gitee…&#xff09;搜索是否有线程的产品用最熟悉的技术&#xff0c;最快的速度上线如果有经费&#xff1a;考虑商业化解决方案 个人小程序怎么做技术选型的 搜索是否有快速搭建下程序的软件技术选型 后端技…

ESP32CAM,点亮一个LED(Arduino平台)

前言 &#xff08;1&#xff09;在此&#xff0c;吐槽一下乐鑫的函数介绍&#xff0c;真的难找。恶心的一批。气死我了。 &#xff08;2&#xff09;接下来我将会介绍我是如何找到ESP32的Arduino平台的函数库的。你将会知道为啥我这么大的戾气。 &#xff08;3&#xff09;同时…

ChatGPT突然上线APP!iPhone可用、速度更快,GPT-4用量限制疑似取消

新建了一个网站 ChatGPT人工智能中文站 - ChatGPT人工智能中文站http://ai.weoknow.com 每天给大家更新可用的国内可用chatGPT免费镜像站 OpenAIChatGPT正式推出iOS应用程序的官方公告突然发布。 立即在苹果商店的免费列表中排名第二&#xff0c;在效率列表中排名第一。 &am…

depends_on 解决 docker 容器依赖问题

如果你经常使用docker-compose启动服务的话&#xff0c;可能会遇到下面的问题&#xff1a;服务 B 依赖服务 A&#xff0c;需要服务 A 先启动&#xff0c;再启动服务 B 举个例子&#xff0c;在部署 kafka 集群的时候&#xff0c;需要启动两个kafka&#xff0c;并使用zookeeper做…

Python常见面试题. Python中的解包操作及其应用场景

这是个简单的知识点&#xff0c;但有的同学并不理解 unpacking解包 解&#xff0c;对应的是*或者**&#xff0c;也有自动解包之说 包对应的可迭代对象 Python助学大礼包点击跳转获取 目录 一、自动解包二、数据过多的解包*三、星号在函数中的使用四、两个星号的解包五、场…

面试官:MySQL自增主键一定是连续的吗?

测试环境&#xff1a; MySQL版本&#xff1a;8.0 数据库表&#xff1a;T &#xff08;主键id&#xff0c;唯一索引c&#xff0c;普通字段d&#xff09; 如果你的业务设计依赖于自增主键的连续性&#xff0c;这个设计假设自增主键是连续的。但实际上&#xff0c;这样的假设是错的…

在 windows 下如何安装 pytorch?

在 Windows 上安装 PyTorch 可以使用 pip 或 conda 管理包。 以下是使用 pip 安装 PyTorch 的步骤&#xff1a; 打开命令提示符或 PowerShell&#xff1b; 运行以下命令安装 PyTorch&#xff1a; pip install torch torchvision torchaudio如果你需要指定安装的版本&#xff…