Vue开发一个导入数据的组件,以下具体说明整个流程和相关知识点
需求是开发一个数据导入组件,此组件是一个公共组件,而且是个常用组件,在很多功能页面上都会用到。
1.导入文件组件 开发
<template>
<div class="content">
<div class="item">
<span style="color: red">*</span><span style="padding-right: 10px">选择文件</span>
<input ref="excel-upload-input" class="excel-upload-input" type="file" accept=".xlsx, .xls"
@change="handleClick" />
<el-button icon="el-icon-upload2" @click="uploadFile">上传</el-button>
<div style="padding: 10px 10px 0 60px">
<span v-if="rawFile" style="padding-left: 10px; color: #1890ff" @click="openFile">{{ rawFile.name }}</span>
<span v-if="rawFile" style="padding-left: 5px; cursor: pointer" @click="cancelFile"><i
class="el-icon-delete"></i></span>
</div>
</div>
<div class="item download">
<span style="cursor: pointer" @click="downloadMdule">EXCEL模板下载</span>
</div>
<div class="item">
<p>注意</p>
<p>1、数据应该严格按照模板样式填写</p>
<p>2、导入模板中带*号字段均要填写</p>
</div>
<div style=" display: flex; justify-content: flex-end; padding-top: 10px;width: 100%; ">
<el-button @click="close">取 消</el-button>
<el-button type="primary" @click="submit" :loading="loading">确 定</el-button>
</div>
</div>
</template>
<script>
export default {
name: 'importWork',
data() {
return {
rawFile: null,
loading: false
};
},
props: {
tempUrl: "",
},
methods: {
downloadMdule() {
window.open(this.tempUrl, "_blank");
},
uploadFile() {
this.$refs["excel-upload-input"].click();
},
// 上传的文件
handleClick(e) {
console.log(e);
const files = e.target.files;
const rawFile = files[0]; // only use files[0]
const isSizeValid = rawFile.size / 1024 <= 100; // Maximum size: 500k
if (!isSizeValid) {
this.errorTip("文件过大,不能超过100k");
return;
}
if (!rawFile) return;
this.upload(rawFile);
},
upload(file) {
this.rawFile = file;
console.log(file);
},
async submit() {
if (!this.rawFile) {
this.errorTip("请上传文件");
return;
}
const formData = new FormData();
formData.append("file", this.rawFile);
this.loading = true;
this.$emit("handle", formData, (res) => {
this.loading = false;
this.successTip(res.message);
this.$emit("reload");
this.rawFile = null;
this.$refs["excel-upload-input"].value = "";
});
},
close() {
this.$emit("close");
},
cancelFile() {
this.rawFile = null;
this.$refs["excel-upload-input"].value = "";
},
}
}
</script>
<style lang="scss" scoped>
.content {
padding: 0 20px;
.excel-upload-input {
display: none;
z-index: -9999;
}
.item {
padding: 10px 0;
}
.download {
color: #1890ff;
display: flex;
justify-content: space-between;
}
}
</style>
代码分析:
template 和 style 部分略过,这就是普通的上传文件Html的结构,如果这一块不会,那就去补习HTML
script 里面涉及到几个知识点:
props
是父组件向子组件传递数据的一种机制- 通过 props,父组件可以将数据传递给子组件,子组件则可以接收并使用这些数据。
- 此处我接收的是一个 导入模版的字段,导入模版是啥,不解释
this.$refs["excel-upload-input"].click()
this.$refs
是一个用于直接访问 DOM 元素或子组件实例的对象。- 使用
this.$refs["excel-upload-input"].click()
时,通过 ref 属性获取 隐藏的上传文件输入框 元素,并手动触发它的 click 事件。
handleClick
方法 是文件框有变化时触发的,我这里是检测文件大小,实际上可以检测文件格式等等。- 方法内,最后将上传文件的对象,赋值给 rawFile 属性,方便后面调用
this.$emit("handle", formData, (res) => {...}
很重要, 很重要, 很重要this.$emit
是子组件向父组件传递事件和数据的一种方式。- 通过
$emit
,子组件可以触发一个自定义事件,并传递数据给父组件,父组件则可以监听这个事件并做出相应的处理。- 由于导入数据的功能肯定是每个父组件独立的功能,很少情况下,所有上传数据会请求到同一接口,但不排除这种情况,此处不做计较
- 此次导入数据的逻辑就是,上传组件只负责上传,处理数据是父组件自己处理,然后将结果给上传组件,上传组件根据结果,来显示成功和失败。
handle
是父组件的定义的事件,后续会说明。formData
是传递的数据(res) => {}
是回调函数,父组件在处理完事件后调用该回调函数并传递结果。父组件使用,会在下面展示。
其他的相关代码,不做解释,都是常规操作
2.调用方,即父组件 调用
<el-dialog title="批量导入" :visible.sync="importDataDialog.dialogVisible" width="1000px" :close-on-click-modal="false">
<importData v-if="importDataDialog.tempUrl" @close="closeImportData" @handle="handleImportData"
@reload="reloadImportData" ref="importDataRef" :tempUrl="importDataDialog.tempUrl">
</importData>
</el-dialog>
<script>
//处理批量导入
async handleImportData(formData, callback) {
console.log(formData)
let res = await importOrderData(formData);
callback(res);
},
</script>
父组件调用就很简单了
importDataDialog.tempUrl
是模版url,我用if
判断,如果没值,上传组件不加载,因为需求是必须让用户先下载模版:tempUrl="importDataDialog.tempUrl"
即父组件给子组件传递数据,子组件用props
获取@handle
父组件监听事件,等待子组件的调用handleImportData
是父组件监听后,处理上传数据的方法- Vue.js 中,
async 和 await
是 JavaScript 中用于处理异步操作的语法糖。可以使用 async 和 await 来处理异步操作,比如 API 请求、定时器等。 - 上传数据处理完成后,返回结果
res
通过 回调函数callback
传统数据 - callback 接收到数据,进行相应的判断,提示等等逻辑
- Vue.js 中,
上述一个最简单的公用上传组件开发完成,接下来就是调试。然后根据用户需求,继续完善优化组件。