使用web worker加速文件流转换速度
1、在public文件夹下创建csv.worker.js
,这里用到papaparse库,将papaparse.min.js
放在同级目录下
// import Papa from 'papaparse'
// web worker中使用import是无效的,这里把papaparse.min.js也放在public文件夹下
importScripts('papaparse.min.js')
self.onmessage = ({ data }) => {
if (data) {
const stream = data[0]
const isText = data[1]
const blob = new Blob([stream])
const reader = new FileReader()
reader.readAsText(blob)
reader.onload = function () {
if (isText) {
// 文本格式
self.postMessage(this.result)
} else {
// 非文本格式
Papa.parse(this.result, {
header: true, // 第一行作为表头
skipEmptyLines: true,
complete: (results) => {
results.data.forEach((e, i) => {
e.rowId = i
e.isShow = true
e.isEdit = false
e.rowComment = ''
})
self.postMessage(results);
},
error: (error) => {
self.postMessage({ error: error.message });
},
});
}
}
}
};
2、vue中使用
// 接口获取文件内容
getContent(JSON.stringify(query)).then((res) => {
if (!res.code) {
// 使用web worker
const worker = new Worker('./csv.worker.js')
worker.onmessage = ({ data }) => {
if (this.istext) { // istext区分文本文件和csv文件
this.textcontent = data
this.loading = false
} else {
this.column = data.meta.fields
this.csvcontent = data.data
this.loading = false
}
worker.terminate()
}
worker.postMessage([res, this.istext])
} else {
this.loading = false
}
})
手动分页
computed: {
pagedData() {
const start = (this.currentPage - 1) * this.pageSize
const end = start + this.pageSize
return this.csvcontent.slice(start, end)
}
}
3、html部分
<pre v-if="istext" v-loading="loading">{{ textcontent }}</pre>
<el-table
v-else
ref="table"
v-loading="loading"
row-key="rowId"
element-loading-text="拼命加载中"
element-loading-spinner="el-icon-loading"
element-loading-background="rgba(0, 0, 0, 0.8)"
:row-class-name="rowClassName"
border
:data="pagedData"
>
<el-table-column type="index" label="序号" width="50">
<template slot-scope="scope">
{{ (currentPage - 1) * pageSize + scope.$index + 1 }}
</template>
</el-table-column>
<el-table-column type="selection" reserve-selection width="43" />
<el-table-column
v-for="item in column"
:key="item"
:label="item"
:prop="item"
min-width="120"
sortable="custom"
>
<template slot-scope="scope">
<span>{{ scope.row[item] }}</span>
</template>
</el-table-column>
<el-table-column
label="Comment"
prop="rowComment"
min-width="110"
sortable="custom"
>
<template slot-scope="scope">
<span v-if="!scope.row.isEdit">{{ scope.row.rowComment ? scope.row.rowComment : '' }}</span>
<div v-else class="el-input">
<input v-model.lazy="scope.row.rowComment" class="el-input__inner" @blur="handleSaveComment(scope.row)">
</div>
</template>
</el-table-column>
</el-table>
注意:数据量很大时,使用input lazy不会卡顿