前言:
在之前的项目中,利用`el-upload`实现了上传图片视频的预览。项目上线后,经使用人员反馈,上传图片、视频每次要先保存到本地然后再上传,很是浪费时间,公司客服人员时间又很紧迫(因为要响应下一位客户的咨询),所以想直接复制图片到表单中,实现自动上传。OK,需求就是这么来得,下面是实现过程。
要上传图片,肯定要先拿到图片的信息,比如图片url、base64、大小、名称等等。那复制时怎么拿图片信息呢?
本文中使用了富文本编辑器来实现图片的复制粘贴功能,我们也可以通过监听鼠标的复制粘贴事件来实现。
使用的富文本编辑器:快速开始 | wangEditor
1、安装富文本编辑器
npm install @wangeditor/editor --save
npm 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"
/>
/*引用组件*/
<Editor
id="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="#"
disabled
accept=".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 = this
const 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',
// 单个文件的最大体积限制,默认为 2M
maxFileSize: 10 * 1024 * 1024,
// 最多可上传几个文件,默认为 100
maxNumberOfFiles: 10,
// 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制,则设置为 []
allowedFileTypes: ['image/*'],
// 小于该值就插入 base64 格式(而不上传),默认为 0
base64LimitSize: 10 * 1024 * 1024,
// 自定义增加 http header
headers: {
'Admin-Token': Lockr.get('Admin-Token')
},
// 超时时间,默认为 10 秒
timeout: 60 * 1000,
// 上传之前处触发
onBeforeUpload(file) {
const fileObj = Object.values(file)[0].data
console.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) return
const { alt, src } = imageNode
const 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 元素的 hoverbar
menuKeys: ['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.url
this.$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