本文基于vue-cli使用proxy代理调用百度第三方接口,使用Excel进行坐标批量转换,遵守自定义tslint规范。
1 表格
效果图:
表格批量导入导出,在此文章已经有详细赘述。
此处主要描述是将js改写成ts所遇到的坑🕳。
在读取成Uint8Array,再转换为Unicode编码时,之前的js中,这样写是没问题的,但是在ts中则会报类型不匹配的错误,需要使用as转换成相匹配的类型。
// js
let bytes = new Uint8Array(reader.result);
// ts
let bytes = new Uint8Array(reader.result as ArrayBuffer);
此外,在导出excel函数中,之前使用ES6语法的const { columns } = this;在ts响应会出现错误。
const { columns } = this;
//等于
const columns = this.columns;
可以使用原生js,当然也可以使用tslint的校验忽略:在代码上一行加上tslint注释// tslint:disable。
2 处理坐标
将上传与导出做成按钮组件,在上传文件后,选用vuex进行非关系型组件之间通信。
2.1 vuex模块化
store目录如下:
采用vuex中的modules模块化。在StoreFactory.ts文件中,封装store类。user.ts中写具体的user模块内成员变量,mutiations、actions中的方法名使用storeConst成员变量。
import { StoreDataModuleBase } from '../helper/StoreFactory';
import StoreConst from '../storeConst';
// tslint:disable-next-line: class-name
export class excelData {
public data: object[] = [];
}
class StateDcvMain {
public excel_Data: excelData = new excelData();
}
export const StoreData = new StoreDataModuleBase<StateDcvMain, any>(
new StateDcvMain(),
// getter
{
GetExcelData: (state: StateDcvMain, getters: any) => {
return state.excel_Data;
}
},
// mutiations
{
[StoreConst.UPDATE_DATA]: (state: StateDcvMain, value: excelData) => {
state.excel_Data = value;
}
},
// actions
{
[StoreConst.UPDATE_DATA_COMMIT]: ({ commit }: any, value: any) => {
return new Promise((resolve, reject) => {
commit('UpdateData', value);
resolve();
});
}
}
);
// storeConst.ts
export default class StoreConst {
public static UPDATE_DATA = 'UpdateData';
public static UPDATE_DATA_COMMIT = 'UpdateDataCommit';
}
在index的Vuex中声明modulesStoreData。
const Store = new Vuex.Store({
modules: {
StoreData
}
});
export default Store;
在导入文件,获取文件json后,将其写入vuex的excel_Data中。
that.$store.dispatch('UpdateDataCommit', that.upData).then(() => {
if (that.$store.getters.GetExcelData.length !== 0) {
alert('上传成功!');
}
// 读取
console.log(this.$store.getters.GetExcelData);
2.2 处理数据
查看百度api,可以发现,转换接口一次上限传递100个坐标,此时,就需要考虑上传的json数组长度是否超过100。 将导出excel绑定down方法,
<template>
<div class="export">
<button @click="down">
<slot>导出Excel</slot>
</button>
</div>
</template>
private points: object[] = [];
private down() {
this.points = this.$store.getters.GetExcelData;
this.points.length <= 100
? this.change1(this.points)
: this.change2(this.points);
this.ExportExcel();
}
// 获取到的数据格式:
// [
// { x: '121.325543', y: '31.763342' },
// { x: '121.355543', y: '31.463342' },
// { x: '121.324543', y: '31.763352' }
// ]
// 需要处理成的格式
// '114.21892734521,29.575429778924;114.21892794521,29.575429778924;114.21892734521,29.579029778924'
此时需要分两种情况讨论:
- 长度小于100
使用map遍历数组,进行字符串拼接。
private change1(p: object[]) {
let str = p.map((_: any) => _.x + ',' + _.y + ';').join('');
this.changeBd(str.substring(0, str.lastIndexOf(';')));
}
- 长度大于100
使用group方法,将其分成最大长度为100的二维数组,再使用map进行遍历(reduce也可)。
private change2(p: object[]) {
// tslint:disable
this.group(p, 100).map(_ => {
let s = _.map((c: any) => c.x + ',' + c.y + ';').join('');
this.changeBd(s.substring(0, s.lastIndexOf(';')));
});
}
// 数组变为多维数组
private group(array: object[], subGroupLength: number) {
let index = 0;
let newArray = [];
while (index < array.length) {
newArray.push(array.slice(index, (index += subGroupLength)));
}
return newArray;
}
3 调用第三方接口
百度web服务API可查看接口功能介绍。
安装好axios(yarn add axios),采用局部导入即可。
接口调用代码如下,获取到数据后需要将多维转为一维,将一维数组导出成excel。
private changeBd(arg: string) {
$axios
.get(
'/api/geoconv/v1/?coords=' +
arg +
'&from=1&to=5&ak=G54LAaflEVRcUG0CfwtdONWRDFuACnWa'
)
// tslint:disable
.then(res => {
// 拿到后台数据赋值给前端
this.newArr.push(res.data.result);
// 降维
this.newArr = this.newArr.reduce((p: any, c: any) => p.concat(c), []);
})
// tslint:disable
.catch(err => {
console.log('错误信息:' + err);
});
}
在调用的时候,如果直接拼成百度的接口,会出现跨域问题。使用第三方接口的时候可以使用proxy代理,或者后端代理。在此我使用vue的proxy代理。
proxy代理:在项目根目录新建一个vue.config.js文件。
module.exports = {
publicPath: "/",
devServer: {
proxy: {
'/api': {
target: 'http://api.map.baidu.com',
changeOrigin: true,//是否跨域 开启代理:在本地创建一个虚拟服务器
// ws: true,//是否代理websockets
// secure: false,//如果是https接口,需要配置这个参数
pathRewrite: { '^/api': '' } //重写路径
}
},
open: true
},
}
点击clying GitHub可查看源码。