效果
1.
2.点击文本域的时候放大宽度
3.
4.上传成功的效果
实现代码
<div class="upLoad">
<el-input
resize="none"
:autosize="autosize"
type="textarea"
placeholder="请输入内容"
v-model="upLoadtextarea"
maxlength="800"
show-word-limit
class="upLoad_text"
@focus="handleFocus"
ref="myTextarea"></el-input>
<div class="btn_box" v-show="showButtons">
<el-tooltip placement="top">
<div slot="content">
添加附件:<br />
1.支持的附件格式有Word、Excel、PPT、XMind、TXT、JPG、PNG <br />
2.单个附件大小不得超过5M <br />
3.附件总数不得超过6个 <br />
</div>
<el-upload
class="upload-demo"
ref="upload"
:action="URL"
:multiple="true"
:limit="6"
:on-exceed="handleExceed"
:before-upload="beforeUpload"
:file-list="fileList"
:on-change="handleChange"
:on-remove="handleRemove"
:on-preview="handlePreview"
:auto-upload="false"
accept=".doc,.docx,.xls,.xlsx,.ppt,.pptx,.xmind,.txt,.jpg,.jpeg,.png">
<el-button size="small" icon="el-icon-upload">上传附件</el-button>
</el-upload>
</el-tooltip>
<div class="rig_btn">
<el-button size="small" type="info" @click="handleCancel">取消</el-button>
<el-button size="small" type="success" @click="Upload">提交</el-button>
</div>
</div>
</div>
它包含了一个文本域和一个文件上传组件。以下是详细解析:
1. **文本域(`el-input`)**:
- `resize="none"` 设置文本域不可调整大小。
- `:autosize="autosize"` 使文本域自动调整尺寸以适应内容。
- `type="textarea"` 指定输入类型为多行文本域。
- `placeholder="请输入内容"` 设置文本域的占位符。
- `v-model="upLoadtextarea"` 创建了数据绑定,将文本域的值与 `upLoadtextarea` 变量同步。
- `maxlength="800"` 设置文本域的最大长度为800个字符。
- `show-word-limit` 显示字数统计。
- `class="upLoad_text"` 设置文本域的类名。
- `@focus="handleFocus"` 在文本域获得焦点时调用 `handleFocus` 方法。
- `ref="myTextarea"` 将文本域引用命名为 `myTextarea`。
2. **文件上传组件(`el-upload`)**:
- `class="upload-demo"` 设置文件上传组件的类名。
- `ref="upload"` 将文件上传组件引用命名为 `upload`。
- `:action="URL"` 设置文件上传的URL。
- `:multiple="true"` 允许上传多个文件。
- `:limit="6"` 限制最多上传6个文件。
- `:on-exceed="handleExceed"` 当尝试上传超过限制数量的文件时调用 `handleExceed` 方法。
- `:before-upload="beforeUpload"` 在文件上传前调用 `beforeUpload` 方法。
- `:file-list="fileList"` 设置文件列表。
- `:on-change="handleChange"` 当文件列表变化时调用 `handleChange` 方法。
- `:on-remove="handleRemove"` 当文件被移除时调用 `handleRemove` 方法。
- `:on-preview="handlePreview"` 当点击文件预览时调用 `handlePreview` 方法。
- `:auto-upload="false"` 关闭自动上传功能。
- `accept=".doc,.docx,.xls,.xlsx,.ppt,.pptx,.xmind,.txt,.jpg,.jpeg,.png"` 限制上传文件的类型。
- `<el-button size="small" icon="el-icon-upload">上传附件</el-button>` 创建一个按钮来触发文件上传。
3. **工具提示(`el-tooltip`)**:
- 包含一个工具提示,当鼠标悬停在按钮上时显示。
- `placement="top"` 设置工具提示的显示位置为顶部。
- `<div slot="content">` 定义了工具提示的内容。
4. **按钮(`el-button`)**:
- `class="rig_btn"` 设置按钮的类名。
- `<el-button size="small" type="info" @click="handleCancel">取消</el-button>` 创建一个按钮,当点击时调用 `handleCancel` 方法。
- `<el-button size="small" type="success" @click="Upload">提交</el-button>` 创建一个按钮,当点击时调用 `Upload` 方法。
5. **`v-show="showButtons"`**:
- 条件性地显示 `.btn_box` 类名所在的元素,当 `showButtons` 为 `true` 时显示,为 `false` 时隐藏。
6. **`handleFocus`、`handleExceed`、`beforeUpload`、`handleChange`、`handleRemove`、`handlePreview`、`handleCancel`、`Upload`**:
- 这些是组件的方法,用于处理文本域和文件上传的各种事件,例如文本域聚焦、文件超出限制、文件上传前、文件列表变化、文件移除、文件预览、取消和提交等。
handleFocus方法
- 当文本域获得焦点时,
handleFocus
方法被调用。 this.autosize = { minRows: 5, maxRows: 5 };
更新autosize
属性,使文本域至少显示5行,最多显示5行。this.showButtons = true;
将showButtons
变量设置为true
,以显示按钮。$nextTick(() => { ... });
确保在DOM更新后执行下一步操作。this.$refs.myTextarea.resizeTextarea();
强制更新文本域大小,使其符合新的autosize
属性设置。-
autosize
对象:autosize
是一个对象,定义了文本域的高度。minRows
属性设置文本域的最小行数。maxRows
属性设置文本域的最大行数。
// Input 获得焦点时触发
handleFocus(e) {
this.autosize = { minRows: 5, maxRows: 5 };
this.showButtons = true;
this.$nextTick(() => {
// 强制更新文本域大小
this.$refs.myTextarea.resizeTextarea();
});
},
handleCancel方法
- 在用户点击取消按钮时调用。
- 首先清空文本域内容。
- 然后清空文件列表。
- 恢复文本域的高度设置。
- 隐藏按钮组。
- 清除临时附件。
//取消
handleCancel() {
this.upLoadtextarea = ""; //清空文本域内容
this.fileList = []; //清空附件
(this.autosize = { minRows: 2, maxRows: 6 }), //恢复文本域高度
this.$nextTick(() => {
// 强制更新文本域大小
this.$refs.myTextarea.resizeTextarea();
});
this.showButtons = false; //隐藏按钮组
// 清除临时附件
this.clearTemporaryAttachment();
},
beforeUpload 方法:
- 在文件上传之前调用,用于检查文件大小是否超过5MB。
- isLt5M 是一个布尔值,表示文件大小是否小于5MB。
- 如果文件大小超过5MB,则显示一个错误消息,并返回 false 阻止文件上传。
- 否则返回 true 允许文件上传。
// 检查每个文件大小是否超过 5M
beforeUpload(file) {
const isLt5M = file.size / 1024 / 1024 < 5;
if (!isLt5M) {
this.$message.error("单个附件大小不得超过 5M");
}
return isLt5M;
},
handleExceed 方法:
- 当尝试上传的文件数量超过限制(6个)时调用。
- 显示一个警告消息,并阻止文件上传。
// 处理超过文件数量限制的情况
handleExceed(files, fileList) {
this.$message.warning("附件总数不得超过 6 个");
},
handleChange 方法:
- 当文件列表发生变化时调用,例如文件被添加或修改。
- 更新 fileList 变量以反映当前的文件列表状态。
// 当文件列表发生变化时的处理
handleChange(file, fileList) {
this.fileList = fileList;
},
handleRemove 方法:
- 当文件被移除时调用。
- 更新 fileList 变量以反映当前的文件列表状态。
// 当文件被移除时的处理
handleRemove(file, fileList) {
this.fileList = fileList;
},
handlePreview 方法:
- 当用户想要预览一个文件时调用。
- 使用 window.navigator.msSaveOrOpenBlob(适用于IE和Edge)或创建一个临时的 a 标签来下载文件。
- 确保在下载完成后释放创建的 ObjectURL,以避免内存泄漏。
- 预上传此时还没到后端处理没走接口没有到服务器
- 这一步完成后,预上传的附件可以下载删除 (图三注释)
// 附件为上传到附件时下载
handlePreview(file) {
if (window.navigator.msSaveOrOpenBlob) {
navigator.msSaveBlob(file.raw, file.name);
} else {
var link = document.createElement("a");
link.download = file.name;
link.href = window.URL.createObjectURL(file.raw);
link.click();
window.URL.revokeObjectURL(link.href);
}
},
clearTemporaryAttachment 方法:
- 这个方法用于清除临时创建的 a 标签和 ObjectURL。
- 通过检查 temporaryLink 和 temporaryObjectUrl 变量来判断是否有需要清除的元素。
- 如果有,则从DOM中移除 a 标签或释放 ObjectURL。
- 最后将 temporaryLink 和 temporaryObjectUrl 设置为 null,以避免内存泄漏。
- 在上传附件成功后清楚遗留的预加载附件
// 清除临时附件
clearTemporaryAttachment() {
// 如果存在临时的a标签,则移除它
if (this.temporaryLink) {
document.body.removeChild(this.temporaryLink);
this.temporaryLink = null;
}
// 如果是使用window.URL.createObjectURL创建的URL,则释放它
if (this.temporaryObjectUrl) {
window.URL.revokeObjectURL(this.temporaryObjectUrl);
this.temporaryObjectUrl = null;
}
},
Upload 方法:
- 在用户点击提交按钮时调用。
- 首先检查文本域内容是否为空,如果为空,则显示错误消息并返回,不执行上传操作。
- 创建一个 FormData 实例来存储要上传的数据。
- 将文本域的内容添加到 FormData 中,使用与后端期望的字段名匹配的键名(在这个例子中是 "content")。
- 将文件列表中的每个文件添加到 FormData 中,使用与后端期望的字段名匹配的键名(在这个例子中是 "annexList")。
- 将其他必要的数据(如 "spuId")添加到 FormData 中。
- 使用 followsaveFollow 函数异步上传 FormData。
- 如果上传成功(即后端返回的状态码为200),则显示成功消息,调用 getCommentsectionList 获取评论区列表,清除临时附件,并清空文本域和文件列表。
- 最后,将文本域内容设置为空,并恢复文本域的高度设置。
// 提交 (文本信息、文件流)
async Upload() {
if (this.upLoadtextarea === "") {
this.$message.error("跟进事务内容不能为空");
return;
}
// 创建一个FormData实例来存储要上传的数据
const formData = new FormData();
// 添加文本内容
formData.append("content", this.upLoadtextarea); // 使用与后端期望的字段名匹配的键
// 添加附件
this.fileList.forEach((file, index) => {
formData.append("annexList", file.raw); // 添加文件对象
});
// 添加其他必要的数据,如spuId
formData.append("spuId", this.shopID);
try {
const res = await followsaveFollow(formData);
if (res.data.code === 200) {
this.$message({
type: "success",
message: "提交事务成功 "
});
this.getCommentsectionList(); //评论区
// 清除临时附件
this.clearTemporaryAttachment();
}
this.upLoadtextarea = ""; //清空文本域内容
this.fileList = []; // 清空附件列表,设置为一个空数组
} catch (error) {}
},