前言:
在之前的项目中,利用`el-upload`实现了上传图片视频的预览。项目上线后,经使用人员反馈,上传图片、视频每次要先保存到本地然后再上传,很是浪费时间,公司客服人员时间又很紧迫(因为要响应下一位客户的咨询),所以想直接复制图片到表单中,实现自动上传。OK,需求就是这么来得,下面是实现过程。
要上传图片,肯定要先拿到图片的信息,比如图片url、base64、大小、名称等等。那复制时怎么拿图片信息呢?
本文中使用了富文本编辑器来实现图片的复制粘贴功能,我们也可以通过监听鼠标的复制粘贴事件来实现。
使用的富文本编辑器:快速开始 | wangEditor
1、安装富文本编辑器
npm install @wangeditor/editor --savenpm install @wangeditor/editor-for-vue --save
2、引入组件
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
3、使用组件
视图:
<el-form-item label="上传图片" class="myUpload"><div slot="label" style="display:block;">上传图片<span style="color:#999999;">(最多10张,单张不能超过10M)</span></div><div style="margin:1px 0 10px;border: 1px solid #ccc;display:inline-block;">/*引用组件*/<Toolbar:editor="editor":default-config="toolbarConfig":mode="mode"style="visibility: hidden;height:0; border-bottom: 1px solid #ccc"/>/*引用组件*/<Editorid="wangEditor"v-model="html":default-config="editorConfig":mode="mode"style="height: 45px; overflow-y: hidden;"@onCreated="onCreated"/></div><el-upload:auto-upload="false":limit="10":file-list="imageList"action="#"disabledaccept=".jpg,.jpeg,.png,.mp4"list-type="picture-card"><i slot="default" class="el-icon-plus"></i><div slot="file" slot-scope="{ file }"><img :src="file.url" class="el-upload-list__item-thumbnail" alt="" /><div class="el-upload-list__item-actions"><span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)"><i class="el-icon-zoom-in"></i></span><span class="el-upload-list__item-delete" @click="handleRemoveImg(file)"><i class="el-icon-delete"></i></span></div></div></el-upload></el-form-item>
1、根据自己需要添加样式
2、`style="visibility: hidden;height:0; border-bottom: 1px solid #ccc"`隐藏富文本工具栏,我们只是复制图片,用不到工具栏
JS:
created() {const that = thisconst api = process.env.NODE_ENV === 'production' ? 'https://生产' : 'http://测试'// 配置图片上传,要在此处配置,编辑器创建以后,再赋值就不起作用了this.editorConfig.MENU_CONF['uploadImage'] = {server: api + '/summary/upload',// form-data fieldName ,默认值 'wangeditor-uploaded-image'fieldName: 'file',// 单个文件的最大体积限制,默认为 2MmaxFileSize: 10 * 1024 * 1024,// 最多可上传几个文件,默认为 100maxNumberOfFiles: 10,// 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制,则设置为 []allowedFileTypes: ['image/*'],// 小于该值就插入 base64 格式(而不上传),默认为 0base64LimitSize: 10 * 1024 * 1024,// 自定义增加 http headerheaders: {'Admin-Token': Lockr.get('Admin-Token')},// 超时时间,默认为 10 秒timeout: 60 * 1000,// 上传之前处触发onBeforeUpload(file) {const fileObj = Object.values(file)[0].dataconsole.log('fileObj:', fileObj)const isJPG = fileObj.type == 'image/jpg' || fileObj.type == 'image/jpeg' || fileObj.type == 'image/png'if (!isJPG) {that.$message.error('图片只能是 JPG、GIF、PNG 格式!')return false}},// 文件上传失败onFailed(file, res) {console.log(`${file.name} 上传失败`, res)},// 文件上传成功之后onSuccess(file, res) {console.log(`${file.name} 上传成功`, res)}// 上传成功自动插入// customInsert(res, insertFn) {// console.log('res:', res)// 从 res 中找到 url ,然后插入图片// insertFn(res.url)// }}// 插入图片后执行(base64格式会自动插入)this.editorConfig.MENU_CONF['insertImage'] = {onInsertedImage(imageNode) {console.log('node:', imageNode)if (imageNode == null) returnconst { alt, src } = imageNodeconst obj = {name: alt,fileBase64: src,url: src}that.imageList.push(obj)if (that.imageList.length > 10) {that.imageList = that.imageList.splice(0, 10)}that.editor.setHtml('<div></div>')}}this.editorConfig.hoverbarKeys = {image: {// 配置 image 元素的 hoverbarmenuKeys: ['imageWidth30', 'imageWidth100', 'deleteImage']}}},methods:{// 初始化编辑器onCreated(editor) {console.log('初始化编辑器')this.editor = Object.seal(editor)if (this.editor && !this.detail) {// this.editor.setHtml('<div></div>')}},// 移除图片文件handleRemoveImg(file) {this.imageList.map((item, index) => {if (item.name === file.name) {// 全量编辑表单时if (item.type === 2) {item.type = 1 // 2 保留 1 删除this.newImgList = this.imageList.splice(index, 1)} else {// 新增图片时this.imageList.splice(index, 1)}}})},// 预览图片handlePictureCardPreview(file) {this.dialogImageUrl = file.urlthis.$alert(`<img src="${this.dialogImageUrl}" width="100%">`, {dangerouslyUseHTMLString: true,callback: () => {}})},}
1、初始化富文本编辑器
2、默认配置一定要写在`created()`生命周期里,否则初始化时会检测不到
3、上面代码中虽然配置了上传图片API,但是没有用到,因为图片默认使用了`base64格式`而不上传
4、因为没有使用图片上传,所以上传相关的事件没有触发
5、使用`base64`格式插入图片后,会触发`onInsertedImage`事件
6、默认配置时可以设置一个空`div`,解决样式问题
详情参考:菜单配置 | wangEditor开源 Web 富文本编辑器,开箱即用,配置简单https://www.wangeditor.com/v5/menu-config.html#%E5%9B%BE%E7%89%87