element-ui 图片上传 及 quillEditor富文本(图片视频上传)

<template><div class="card" style="overflow: hidden; padding-bottom: 10px"><div style="padding: 20px 20px 0 20px"><span class="title_top"><span class="top_icon"></span>基本信息</span><el-divider></el-divider></div><div class="box"><div><div class="box_count"><div class="box_l"><FlexLinePI :title="'图文标题'" :dropshow="true"><el-input v-model.trim="ruleForm.title" maxlength="20" show-word-limit type="text" placeholder="请输入标题"v-clear-emoij @input="e => (ruleForm.title = formateText(e))"></el-input></FlexLinePI><FlexLinePI :title="'图文摘要'" :dropshow="true"><el-input style="white-space: pre-wrap;word-break: break-all;"v-model.trim="ruleForm.note" type="textarea" maxlength="150" show-word-limit rows="5"placeholder="请输入正文详情" @input="e => (ruleForm.note = formateText(e))"></el-input></FlexLinePI><FlexLinePI :title="'封面图片'" :dropshow="true"><el-upload class="avatar-uploader" :action="upload" :show-file-list="false":on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload" :on-progress="onprogress"><img v-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" style="">( 建议上传图片尺寸100x100px,大小不超过5M )</div></el-upload></FlexLinePI><FlexLinePI :title="'图文描述'" :dropshow="true" :position="false"><div><quill-editor v-model="ruleForm.content" ref="quillEditor" :options="editorOption"></quill-editor><div class="rich-uploader"><!-- 图片上传组件辅助--><el-upload class="rich-uploader2" name="pic" action="" :show-file-list="false" accept=".jpg,.png,jpeg":http-request="httpRequest"></el-upload><AliUpload class="rich-uploader3" :url="videoURL" @deleteVideo="deleteVideo"@beforeupload="beforeupload" @uploadSuccess="uploadVideoSuccess" /><!-- <el-upload class="rich-uploader3" name="pic" action="" :show-file-list="false" accept="video/*":http-request="httpRequestvideo"></el-upload> --></div></div></FlexLinePI><div class="buttom"><el-button type="primary" @click="addandedit(0)" :loading="loadingbtn">{{ loadingbtn == false ? "保存" : "记载中"}}</el-button><el-button type="primary" @click="addandedit(1)" :loading="loadingbtn">{{ loadingbtn == false ? "保存并发布" : "记载中" }}</el-button><!-- <el-button type="primary" @click="look">预览</el-button> --></div></div><div class="box_r" :style="{'background-image': `url(${require('../../../assets/images/phone.png')}`}"><div class="box_r_informationurl"><div class="box_r_inImg"><img src="../../../assets/images/authorlogo.png" alt="" srcset="" style="width: 100%; height: 100%" /></div><div class="box_r_inlanguage" style="width: 180px"><p style="-webkit-line-clamp: 1; font-size: 14px; width: 100%" class="ellipsis">{{ ruleForm.title != "" ? ruleForm.title : "请输入标题" }}</p><div style="display: flex; margin-top: 5px; height: 80px"><div style="flex: 1;-webkit-line-clamp: 6;font-size: 12px;color: #999999;" 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><!-- 图片视频上传中 --><el-dialog title="" :visible.sync="dialogVisiblevideo" width="160px" :close-on-click-modal="false":close-on-press-escape="false" :show-close="false"><span slot="title"></span><div class="loadding_image" style=""><i class="el-icon-loading" style="font-size: 50px;"></i><div>{{ uptext }}</div><div v-if="videosize != ''">此视频有 {{ videosize }} MB大小,请稍等...</div></div></el-dialog></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";
import AliUpload from './component/aliUpload.vue'
Quill.register(video);
export default {name: "AddImageText",components: {quillEditor,AliUpload// , 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: {clipboard: {// 粘贴版,处理粘贴时候带图片matchers: [[Node.ELEMENT_NODE, this.handleCustomMatcher]],},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: "",// 提交loadingbtn: false,dialogVisiblevideo: false,uptext: "",videosize: ""};},mounted() {this.updateId = this.$route.query.idif (this.updateId == undefined) {this.ruleForm = {id: "",title: "",note: "",cover: "",content: ""};} else {// 详情this.getdetail(this.updateId);}// 复制图片到富文本// let quill = this.$refs.quillEditor.quill;// quill.root.addEventListener(//   "paste",//   (evt) => {//     if (//       evt.clipboardData &&//       evt.clipboardData.files &&//       evt.clipboardData.files.length//     ) {//       evt.preventDefault();//       [].forEach.call(evt.clipboardData.files, (file) => {//         if (!file.type.match(/^image\/(gif|jpe?g|a?png|bmp)/i)) {//           return;//         }//         const formdata = new FormData();//         formdata.append("file", file, file.name);//         formdata.append("type", "1");//         // let length = quill.getSelection().index;//         quill.insertEmbed(1, "image", 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(1, "image", res.data.data.real_path);//               //       // 调整光标到最后//               quill.setSelection(1 + 1);//             } else {//               _this.$message.warning(res.data.msg || "数据响应过慢,请稍后再试");//             }//           })//           .catch(err => {//             console.log(err);//           });//       });//     }//   },//   false// );},computed: {},methods: {handleCustomMatcher(node, Delta) {console.log(Delta,123)let ops = []Delta.ops.forEach(op => {if (op.insert && typeof op.insert === 'string') {// 如果粘贴了图片,这里会是一个对象,所以可以这样处理ops.push({insert: op.insert,})} else {this.$message({message: '不允许粘贴图片,请手动上传',type: 'warning'})}})Delta.ops = opsreturn Delta},//handleAvatarSuccess(res, file) {if (res.status == 1) {this.dialogVisiblevideo = false;this.ruleForm.cover = res.data.real_path;}},beforeAvatarUpload(file) {let types = ["image/jpeg","image/jpg","image/png"];const isImage = types.includes(file.type);const isLtSize = file.size / 1024 / 1024 < 5;if (!isImage) {this.$message.warning("上传图片只能是 JPG、JPEG、PNG 格式!");return false;}if (!isLtSize) {this.$message.warning("上传图片大小不能超过 5MB!");return false;}return true;},onprogress(event, file, fileList) {console.log(event, file, fileList);// this.dialogVisiblevideo = true;},// 详情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) {const _this = this;_this.uptext = "图片正在上传中...";_this.videosize = "";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.data.msg || "数据响应过慢,请稍后再试");}}).catch(err => {console.log(err);});},// ==============================================================// 保存编辑addandedit(val) {if (this.ruleForm.title == "") {this.$message.warning("请输入图文标题");return;}if (this.ruleForm.note == "") {this.$message.warning("请输入图文摘要");return;}if (this.ruleForm.cover == "") {this.$message.warning("请上传封面图片");return;}if (this.ruleForm.content == "") {this.$message.warning("请输入图文描述");return;}this.loadingbtn = true;if (this.updateId == undefined) {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.loadingbtn = 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.loadingbtn = false;this.$router.push({name: "ImageText"});} else {this.$message.warning(res.msg || "数据响应过慢,请稍后再试");}}).catch(err => {console.log(err);});},// 视频上传 =================deleteVideo(val) {console.log(val)},beforeupload(val) {this.dialogVisiblevideo = val.isshow;this.uptext = "视频上传中...";this.videosize = Math.ceil(val.filesize / (1024 * 1024));},uploadVideoSuccess(val) {this.$message.success("上传成功");this.dialogVisiblevideo = val.isshow;let quill = this.$refs.quillEditor.quill;let length = quill.getSelection().index;// 插入图片  服务器返回的图片地址quill.insertEmbed(length, "video", val.videoURL);// 调整光标到最后quill.setSelection(length + 1);},//  ======httpRequestvideo(item) {let chunkSize = 1024 * 1024 * 2; // 每个切片的大小(这里设置为2MB)let totalChunks = Math.ceil(item.file.size / chunkSize); // 总切片数let currentChunk = 1; // 当前切片索引var start = currentChunk * chunkSize;var end = Math.min(totalChunks, start + chunkSize);this.dialogVisiblevideo = true;this.videosize = Math.ceil(item.file.size / (1024 * 1024));this.uptext = "视频上传中...";const uploadNextChunk = () => {const formData = new FormData();formData.append("name", item.file.name);formData.append("data", item.file.slice(start, end));// 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 => {this.dialogVisiblevideo = true;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);axios.post(uploadvideo + "?act=join", formdata, {headers: { "Content-Type": "multipart/form-data" }}).then(res => {if (res.data.status == 1) {this.dialogVisiblevideo = false;this.$message.success(res.msg || "完成视频上传");let length = quill.getSelection().index;// 插入图片  服务器返回的图片地址quill.insertEmbed(length, "video", res.data.path);// 调整光标到最后quill.setSelection(length + 1);} else {this.dialogVisiblevideo = false;this.$message.warning(res.data.msg || "数据响应过慢,请稍后再试");}}).catch(error => {this.dialogVisiblevideo = false;console.error("Error uploading file:", error);});}}
};
</script>
<style scoped lang="less">
p {margin: 0;padding: 0;
}.box {width: 90%;// margin: 0 auto;margin-left: 35px;.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: 36px;height: 36px;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;
}/deep/ .el-dialog__header {display: none;
}/deep/ .el-dialog__body {padding: 10px 20px;position: fixed;top: 50%;left: 50%;transform: translate(-50%, -50%);background-color: #ffffff00;color: #ccc;
}.loadding_image {margin: 0 auto;text-align: center;width: 125px;
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/22610.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SQL基础复习与进阶

SQL进阶 文章目录 SQL进阶关键字复习ALLANYEXISTS 内置函数ROUND&#xff08;四舍五入&#xff09;TRUNCATE&#xff08;截断函数&#xff09;SEILING&#xff08;向上取整&#xff09;FLOOR&#xff08;向下取整&#xff09;ABS&#xff08;获取绝对值&#xff09;RAND&#x…

RPC原理与Go RPC详解

文章目录 RPC原理与Go RPC什么是RPC本地调用RPC调用HTTP调用RESTful API net/rpc基础RPC示例基于TCP协议的RPC使用JSON协议的RPCPython调用RPC RPC原理 RPC原理与Go RPC 什么是RPC RPC&#xff08;Remote Procedure Call&#xff09;&#xff0c;即远程过程调用。它允许像调用…

React Native元素旋转一定的角度

mMeArrowIcon: {fontSize: 30, color: #999, transform: [{rotate: 180deg}]},<Icon name"arrow" style{styles.mMeArrowIcon}></Icon>参考链接&#xff1a; https://reactnative.cn/docs/transforms https://chat.xutongbao.top/

ID生成方案总结

分布式ID生成方案 UUID数据库自增号段模式Redis实现雪花算法&#xff08;SnowFlake&#xff09;百度Uidgenerator美团Leaf滴滴TinyID 本文重点介绍能够ID自增的Leaf和TinyID 号段模式 这种模式也是现在生成分布式ID的一种方法&#xff0c;实现思路是会从数据库获取一个号段…

MikTex+TexStudio踩坑记

首先&#xff0c;去这两个的官网&#xff0c;下载安装&#xff0c;都没问题。 第二&#xff0c;记得以管理员方式运行程序&#xff0c;可能会少很多麻烦 第三&#xff0c;编译的时候&#xff0c;命令行提示错误&#xff1a; So far, no MiKTeX administrator has checked fo…

AcWing 24:机器人的运动范围 ← BFS、DFS

【题目来源】https://www.acwing.com/problem/content/description/22/【题目描述】 地上有一个 m 行和 n 列的方格&#xff0c;横纵坐标范围分别是 0∼m−1 和 0∼n−1。 一个机器人从坐标 (0,0) 的格子开始移动&#xff0c;每一次只能向左&#xff0c;右&#xff0c;上&#…

【雕爷学编程】Arduino动手做(182)---DRV8833双路电机驱动模块2

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

【LangChain】Prompts之Prompt templates

Prompts 编程模型的新方法是通过提示(prompts)。 prompts是指模型的输入。该输入通常由多个组件构成。 LangChain 提供了多个类和函数&#xff0c;使构建和使用prompts变得容易。 Prompt templates(提示模板): 参数化模型输入Example selectors(选择器示例): 动态选择要包含在…

EventBus 开源库学习(一)

一、概念 EventBus是一款在 Android 开发中使用的发布-订阅事件总线框架&#xff0c;基于观察者模式&#xff0c;将事件的接收者和发送者解耦&#xff0c;简化了组件之间的通信&#xff0c;使用简单、效率高、体积小。 一句话&#xff1a;用于Android组件间通信的。 二、原理…

TypeScript最新语法总结

注意注意&#xff01;&#xff01;&#xff01;本文介绍的是最新的TypeScript4的重要语法 第一部分&#xff1a;TypeScript的简介 TypeScript 是由微软开发的一款开源的编程语言&#xff0c;TypeScript 是 Javascript 的超集&#xff0c;遵循最新的 ES6、ES5 规范&#xff0c…

做好“关键基础设施提供商”角色,亚马逊云科技加快生成式AI落地

一场关于生产力的革命已在酝酿之中。全球管理咨询公司麦肯锡在最近的报告《生成式人工智能的经济潜力&#xff1a;下一波生产力浪潮》中指出&#xff0c;生成式AI每年可能为全球经济增加2.6万亿到4.4万亿美元的价值。在几天前的亚马逊云科技纽约峰会中&#xff0c;「生成式AI」…

动手学深度学习(二)线性神经网络

推荐课程&#xff1a;跟李沐学AI的个人空间-跟李沐学AI个人主页-哔哩哔哩视频 回归任务是指对连续变量进行预测的任务。 一、线性回归 线性回归模型是一种常用的统计学习方法&#xff0c;用于分析自变量与因变量之间的关系。它通过建立一个关于自变量和因变量的线性方程&…

分布式协议与算法——拜占庭将军问题

拜占庭将军问题 背景&#xff1a;以战国时期为背景 战国时期&#xff0c;齐、楚、燕、韩、赵、魏、秦七雄并立&#xff0c;后来秦国的势力不断强大起来&#xff0c;成了东方六国的共同威胁。于是&#xff0c;这六个国家决定联合&#xff0c;全力抗秦&#xff0c;免得被秦国各个…

JVM面试突击1

JVM面试突击 JDK&#xff0c;JRE以及JVM的关系 我们的编译器到底干了什么事&#xff1f; 仅仅是将我们的 .java 文件转换成了 .class 文件&#xff0c;实际上就是文件格式的转换&#xff0c;对等信息转换。 类加载机制是什么&#xff1f; 所谓类加载机制就是 虚拟机把Class文…

C语言阶段性测试题

大家好&#xff0c;我是深鱼~ 【前言】&#xff1a;本部分是C语言初阶学完阶段性测试题&#xff0c;最后一道编程题有一定的难度&#xff0c;需要多去揣摩&#xff0c;代码敲多了&#xff0c;自然就感觉不难了&#xff0c;加油&#xff0c;铁汁们&#xff01;&#xff01;&…

YOLO中Anchor生成介绍

Anchor生成机制 YOLOv1YOLOv2YOLOv4模型输出decode1.维度变换2.读取位置信息3.坐标变换4.构建网格5. 计算实际偏移量6.得到输出 YOLOv1 利用全连接层直接对边界框进行预测 YOLOv2 YOLOv2通过缩减网络&#xff0c;使用416x416的输入&#xff0c;模型下采样的总步长为32&#…

flutter开发实战-实现自定义按钮类似UIButton效果

flutter开发实战-实现自定义按钮类似UIButton效果 最近开发过程中需要实现一下UIButton效果的flutter按钮&#xff0c;这里使用的是监听手势点击事件。 一、GestureDetector GestureDetector属性定义 GestureDetector({super.key,this.child,this.onTapDown,this.onTapUp,t…

附件展示 点击下载

效果图 实现代码 <el-table-column prop"attachment" label"合同附件" width"250" show-overflow-tooltip><template slot-scope"scope"><div v-if"scope.row.cceedcAppendixInfoList &&scope.row.ccee…

路由的hash和history模式的区别

目录 ✅ 路由模式概述 一. 路由的hash和history模式的区别 1. hash模式 2. history模式 3. 两种模式对比 二. 如何获取页面的hash变化 ✅ 路由模式概述 单页应用是在移动互联时代诞生的&#xff0c;它的目标是不刷新整体页面&#xff0c;通过地址栏中的变化来决定内容区…

SQL 表别名 和 列别名

列表名 列表名之后 order by 可以用别名 也可以用原名&#xff0c; where 中不能用别名的 SQL语句执行顺序&#xff1a; from–>where–>group by -->having — >select --> order 第一步&#xff1a;from语句&#xff0c;选择要操作的表。 第二步&#xff1…