Former-commit-id: e2bfcb0f40765724b17e13056e8293ec271efefb [formerly e2bfcb0f40765724b17e13056e8293ec271efefb [formerly e2bfcb0f40765724b17e13056e8293ec271efefb [formerly e2bfcb0f40765724b17e13056e8293ec271efefb [formerly 5793d72d458b7eeaf28a097d026168cebc9fc256 [formerly 9c8de3644bd40a55711e618742e29cce390e4c5f]]]]]
Former-commit-id: 05ca3c8da65f8583c142720628aa6ea71d2dbf45
Former-commit-id: 7a4d2fba696e901db86071ea2810e9c932c976ad
Former-commit-id: c18d3689200ca0e528fbf9bf171f6e1b50131bc3 [formerly 455e9952ca890cd8ad882250cfb9eabd944d44ee]
Former-commit-id: 021fa8191681fe4f22e9a9f40389831a847e9066
Former-commit-id: 1022b7792417ce366901b9d5284762a015dd6d26
Former-commit-id: bed799410be508713cac76b7c8cf02d4457fe996
Former-commit-id: f6787cfaac3404132ad1011e2707e08484708ca9
Former-commit-id: 7a8a3baca9ef30393744fd56def6d608b51dcddd
This commit is contained in:
liyang
2018-07-16 10:43:14 +08:00
parent c53973a35f
commit 1d310c9c7d
496 changed files with 3 additions and 23673 deletions

View File

@@ -1,22 +0,0 @@
import Vue from 'vue'
import { Message } from 'element-ui'
import axios from 'axios'
// 在这里对返回的数据进行处理
// 在这里添加你自己的逻辑
axios.interceptors.response.use(res => {
if (res.data.code !== undefined) {
if (res.data.code !== 0) {
Message.error(res.data.msg)
return Promise.reject(res.data.msg)
} else {
return res.data.data
}
} else {
return res.data
}
}, err => {
return Promise.reject(err)
})
Vue.prototype.$axios = axios

View File

@@ -1,179 +0,0 @@
/* eslint-disable */
/* Blob.js
* A Blob implementation.
* 2014-05-27
*
* By Eli Grey, http://eligrey.com
* By Devin Samarin, https://github.com/eboyjr
* License: X11/MIT
* See LICENSE.md
*/
/*global self, unescape */
/*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true,
plusplus: true */
/*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */
(function (view) {
"use strict";
view.URL = view.URL || view.webkitURL;
if (view.Blob && view.URL) {
try {
new Blob;
return;
} catch (e) {}
}
// Internally we use a BlobBuilder implementation to base Blob off of
// in order to support older browsers that only have BlobBuilder
var BlobBuilder = view.BlobBuilder || view.WebKitBlobBuilder || view.MozBlobBuilder || (function(view) {
var
get_class = function(object) {
return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1];
}
, FakeBlobBuilder = function BlobBuilder() {
this.data = [];
}
, FakeBlob = function Blob(data, type, encoding) {
this.data = data;
this.size = data.length;
this.type = type;
this.encoding = encoding;
}
, FBB_proto = FakeBlobBuilder.prototype
, FB_proto = FakeBlob.prototype
, FileReaderSync = view.FileReaderSync
, FileException = function(type) {
this.code = this[this.name = type];
}
, file_ex_codes = (
"NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR "
+ "NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR"
).split(" ")
, file_ex_code = file_ex_codes.length
, real_URL = view.URL || view.webkitURL || view
, real_create_object_URL = real_URL.createObjectURL
, real_revoke_object_URL = real_URL.revokeObjectURL
, URL = real_URL
, btoa = view.btoa
, atob = view.atob
, ArrayBuffer = view.ArrayBuffer
, Uint8Array = view.Uint8Array
;
FakeBlob.fake = FB_proto.fake = true;
while (file_ex_code--) {
FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1;
}
if (!real_URL.createObjectURL) {
URL = view.URL = {};
}
URL.createObjectURL = function(blob) {
var
type = blob.type
, data_URI_header
;
if (type === null) {
type = "application/octet-stream";
}
if (blob instanceof FakeBlob) {
data_URI_header = "data:" + type;
if (blob.encoding === "base64") {
return data_URI_header + ";base64," + blob.data;
} else if (blob.encoding === "URI") {
return data_URI_header + "," + decodeURIComponent(blob.data);
} if (btoa) {
return data_URI_header + ";base64," + btoa(blob.data);
} else {
return data_URI_header + "," + encodeURIComponent(blob.data);
}
} else if (real_create_object_URL) {
return real_create_object_URL.call(real_URL, blob);
}
};
URL.revokeObjectURL = function(object_URL) {
if (object_URL.substring(0, 5) !== "data:" && real_revoke_object_URL) {
real_revoke_object_URL.call(real_URL, object_URL);
}
};
FBB_proto.append = function(data/*, endings*/) {
var bb = this.data;
// decode data to a binary string
if (Uint8Array && (data instanceof ArrayBuffer || data instanceof Uint8Array)) {
var
str = ""
, buf = new Uint8Array(data)
, i = 0
, buf_len = buf.length
;
for (; i < buf_len; i++) {
str += String.fromCharCode(buf[i]);
}
bb.push(str);
} else if (get_class(data) === "Blob" || get_class(data) === "File") {
if (FileReaderSync) {
var fr = new FileReaderSync;
bb.push(fr.readAsBinaryString(data));
} else {
// async FileReader won't work as BlobBuilder is sync
throw new FileException("NOT_READABLE_ERR");
}
} else if (data instanceof FakeBlob) {
if (data.encoding === "base64" && atob) {
bb.push(atob(data.data));
} else if (data.encoding === "URI") {
bb.push(decodeURIComponent(data.data));
} else if (data.encoding === "raw") {
bb.push(data.data);
}
} else {
if (typeof data !== "string") {
data += ""; // convert unsupported types to strings
}
// decode UTF-16 to binary string
bb.push(unescape(encodeURIComponent(data)));
}
};
FBB_proto.getBlob = function(type) {
if (!arguments.length) {
type = null;
}
return new FakeBlob(this.data.join(""), type, "raw");
};
FBB_proto.toString = function() {
return "[object BlobBuilder]";
};
FB_proto.slice = function(start, end, type) {
var args = arguments.length;
if (args < 3) {
type = null;
}
return new FakeBlob(
this.data.slice(start, args > 1 ? end : this.data.length)
, type
, this.encoding
);
};
FB_proto.toString = function() {
return "[object Blob]";
};
FB_proto.close = function() {
this.size = this.data.length = 0;
};
return FakeBlobBuilder;
}(view));
view.Blob = function Blob(blobParts, options) {
var type = options ? (options.type || "") : "";
var builder = new BlobBuilder();
if (blobParts) {
for (var i = 0, len = blobParts.length; i < len; i++) {
builder.append(blobParts[i]);
}
}
return builder.getBlob(type);
};
}(typeof self !== "undefined" && self || typeof window !== "undefined" && window || this.content || this));

View File

@@ -1,62 +0,0 @@
/*
inspired by https://www.npmjs.com/package/react-csv-downloader
now removed from Github
inspired by https://github.com/iview/iview
*/
/* eslint-disable */
const newLine = '\r\n';
const appendLine = (content, row, { separator, quoted }) => {
const line = row.map(data => {
if (!quoted) return data;
// quote data
data = typeof data === 'string' ? data.replace(/"/g, '"') : data;
return `"${data}"`;
});
content.push(line.join(separator));
};
const defaults = {
separator: ',',
quoted: false
};
export default function csv(columns, datas, options, noHeader = false) {
options = Object.assign({}, defaults, options);
let columnOrder;
const content = [];
const column = [];
if (columns) {
columnOrder = columns.map(v => {
if (typeof v === 'string') return v;
if (!noHeader) {
column.push(typeof v.label !== 'undefined' ? v.label : v.prop);
}
return v.prop;
});
if (column.length > 0) appendLine(content, column, options);
} else {
columnOrder = [];
datas.forEach(v => {
if (!Array.isArray(v)) {
columnOrder = columnOrder.concat(Object.keys(v));
}
});
if (columnOrder.length > 0) {
columnOrder = columnOrder.filter((value, index, self) => self.indexOf(value) === index);
if (!noHeader) appendLine(content, columnOrder, options);
}
}
if (Array.isArray(datas)) {
datas.forEach(row => {
if (!Array.isArray(row)) {
row = columnOrder.map(k => (typeof row[k] !== 'undefined' ? row[k] : ''));
}
appendLine(content, row, options);
});
}
return content.join(newLine);
}

View File

@@ -1,83 +0,0 @@
/* eslint-disable */
/*
此代码来源于iview表格组件的CSV导出部分
https://github.com/iview/iview
*/
function has (browser) {
const ua = navigator.userAgent;
if (browser === 'ie') {
const isIE = ua.indexOf('compatible') > -1 && ua.indexOf('MSIE') > -1;
if (isIE) {
const reIE = new RegExp('MSIE (\\d+\\.\\d+);');
reIE.test(ua);
return parseFloat(RegExp['$1']);
} else {
return false;
}
} else {
return ua.indexOf(browser) > -1;
}
}
const csv = {
_isIE11 () {
let iev = 0;
const ieold = (/MSIE (\d+\.\d+);/.test(navigator.userAgent));
const trident = !!navigator.userAgent.match(/Trident\/7.0/);
const rv = navigator.userAgent.indexOf('rv:11.0');
if (ieold) {
iev = Number(RegExp.$1);
}
if (navigator.appVersion.indexOf('MSIE 10') !== -1) {
iev = 10;
}
if (trident && rv !== -1) {
iev = 11;
}
return iev === 11;
},
_isEdge () {
return /Edge/.test(navigator.userAgent);
},
_getDownloadUrl (text) {
const BOM = '\uFEFF';
// Add BOM to text for open in excel correctly
if (window.Blob && window.URL && window.URL.createObjectURL) {
const csvData = new Blob([BOM + text], { type: 'text/csv' });
return URL.createObjectURL(csvData);
} else {
return 'data:attachment/csv;charset=utf-8,' + BOM + encodeURIComponent(text);
}
},
download (filename, text) {
if (has('ie') && has('ie') < 10) {
// has module unable identify ie11 and Edge
const oWin = window.top.open('about:blank', '_blank');
oWin.document.charset = 'utf-8';
oWin.document.write(text);
oWin.document.close();
oWin.document.execCommand('SaveAs', filename + '.csv');
oWin.close();
} else if (has('ie') === 10 || this._isIE11() || this._isEdge()) {
const BOM = '\uFEFF';
const csvData = new Blob([BOM + text], { type: 'text/csv' });
navigator.msSaveBlob(csvData, filename + '.csv');
} else {
const link = document.createElement('a');
link.download = filename + '.csv';
link.href = this._getDownloadUrl(text);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
}
};
export default csv;

View File

@@ -1,145 +0,0 @@
/* eslint-disable */
// 来源于网络 有细微改动
import './_blob'
import FileSaver from 'file-saver'
import XLSX from 'xlsx'
function generateArray(table) {
var out = [];
var rows = table.querySelectorAll('tr');
var ranges = [];
for (var R = 0; R < rows.length; ++R) {
var outRow = [];
var row = rows[R];
var columns = row.querySelectorAll('td');
for (var C = 0; C < columns.length; ++C) {
var cell = columns[C];
var colspan = cell.getAttribute('colspan');
var rowspan = cell.getAttribute('rowspan');
var cellValue = cell.innerText;
if (cellValue !== "" && cellValue == +cellValue) cellValue = +cellValue;
//Skip ranges
ranges.forEach(function (range) {
if (R >= range.s.r && R <= range.e.r && outRow.length >= range.s.c && outRow.length <= range.e.c) {
for (var i = 0; i <= range.e.c - range.s.c; ++i) outRow.push(null);
}
});
//Handle Row Span
if (rowspan || colspan) {
rowspan = rowspan || 1;
colspan = colspan || 1;
ranges.push({s: {r: R, c: outRow.length}, e: {r: R + rowspan - 1, c: outRow.length + colspan - 1}});
}
;
//Handle Value
outRow.push(cellValue !== "" ? cellValue : null);
//Handle Colspan
if (colspan) for (var k = 0; k < colspan - 1; ++k) outRow.push(null);
}
out.push(outRow);
}
return [out, ranges];
};
function datenum(v, date1904) {
if (date1904) v += 1462;
var epoch = Date.parse(v);
return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
}
function sheet_from_array_of_arrays(data, opts) {
var ws = {};
var range = {s: {c: 10000000, r: 10000000}, e: {c: 0, r: 0}};
for (var R = 0; R != data.length; ++R) {
for (var C = 0; C != data[R].length; ++C) {
if (range.s.r > R) range.s.r = R;
if (range.s.c > C) range.s.c = C;
if (range.e.r < R) range.e.r = R;
if (range.e.c < C) range.e.c = C;
var cell = {v: data[R][C]};
if (cell.v == null) continue;
var cell_ref = XLSX.utils.encode_cell({c: C, r: R});
if (typeof cell.v === 'number') cell.t = 'n';
else if (typeof cell.v === 'boolean') cell.t = 'b';
else if (cell.v instanceof Date) {
cell.t = 'n';
cell.z = XLSX.SSF._table[14];
cell.v = datenum(cell.v);
}
else cell.t = 's';
ws[cell_ref] = cell;
}
}
if (range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range);
return ws;
}
function Workbook() {
if (!(this instanceof Workbook)) return new Workbook();
this.SheetNames = [];
this.Sheets = {};
}
function s2ab(s) {
var buf = new ArrayBuffer(s.length);
var view = new Uint8Array(buf);
for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
return buf;
}
export function export_table_to_excel(id) {
var theTable = document.getElementById(id);
console.log('a')
var oo = generateArray(theTable);
var ranges = oo[1];
/* original data */
var data = oo[0];
var ws_name = "SheetJS";
console.log(data);
var wb = new Workbook(), ws = sheet_from_array_of_arrays(data);
/* add ranges to worksheet */
// ws['!cols'] = ['apple', 'banan'];
ws['!merges'] = ranges;
/* add worksheet to workbook */
wb.SheetNames.push(ws_name);
wb.Sheets[ws_name] = ws;
var wbout = XLSX.write(wb, {bookType: 'xlsx', bookSST: false, type: 'binary'});
FileSaver.saveAs(new Blob([s2ab(wbout)], {type: "application/octet-stream"}), "test.xlsx")
}
function formatJson(jsonData) {
console.log(jsonData)
}
export function export_json_to_excel(th, jsonData, defaultTitle) {
/* original data */
var data = jsonData;
data.unshift(th);
var ws_name = "SheetJS";
var wb = new Workbook(), ws = sheet_from_array_of_arrays(data);
/* add worksheet to workbook */
wb.SheetNames.push(ws_name);
wb.Sheets[ws_name] = ws;
var wbout = XLSX.write(wb, {bookType: 'xlsx', bookSST: false, type: 'binary'});
var title = defaultTitle || '列表'
FileSaver.saveAs(new Blob([s2ab(wbout)], {type: "application/octet-stream"}), title + ".xlsx")
}

View File

@@ -1,217 +0,0 @@
/* eslint-disable */
/* Blob.js
* A Blob implementation.
* 2018-01-12
*
* By Eli Grey, http://eligrey.com
* By Devin Samarin, https://github.com/dsamarin
* License: MIT
* See https://github.com/eligrey/Blob.js/blob/master/LICENSE.md
*/
/*global self, unescape */
/*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true,
plusplus: true */
/*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */
(function (view) {
"use strict";
view.URL = view.URL || view.webkitURL;
if (view.Blob && view.URL) {
try {
new Blob;
return;
} catch (e) {}
}
// Internally we use a BlobBuilder implementation to base Blob off of
// in order to support older browsers that only have BlobBuilder
var BlobBuilder = view.BlobBuilder || view.WebKitBlobBuilder || view.MozBlobBuilder || (function(view) {
var
get_class = function(object) {
return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1];
}
, FakeBlobBuilder = function BlobBuilder() {
this.data = [];
}
, FakeBlob = function Blob(data, type, encoding) {
this.data = data;
this.size = data.length;
this.type = type;
this.encoding = encoding;
}
, FBB_proto = FakeBlobBuilder.prototype
, FB_proto = FakeBlob.prototype
, FileReaderSync = view.FileReaderSync
, FileException = function(type) {
this.code = this[this.name = type];
}
, file_ex_codes = (
"NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR "
+ "NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR"
).split(" ")
, file_ex_code = file_ex_codes.length
, real_URL = view.URL || view.webkitURL || view
, real_create_object_URL = real_URL.createObjectURL
, real_revoke_object_URL = real_URL.revokeObjectURL
, URL = real_URL
, btoa = view.btoa
, atob = view.atob
, ArrayBuffer = view.ArrayBuffer
, Uint8Array = view.Uint8Array
, origin = /^[\w-]+:\/*\[?[\w\.:-]+\]?(?::[0-9]+)?/
;
FakeBlob.fake = FB_proto.fake = true;
while (file_ex_code--) {
FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1;
}
// Polyfill URL
if (!real_URL.createObjectURL) {
URL = view.URL = function(uri) {
var
uri_info = document.createElementNS("http://www.w3.org/1999/xhtml", "a")
, uri_origin
;
uri_info.href = uri;
if (!("origin" in uri_info)) {
if (uri_info.protocol.toLowerCase() === "data:") {
uri_info.origin = null;
} else {
uri_origin = uri.match(origin);
uri_info.origin = uri_origin && uri_origin[1];
}
}
return uri_info;
};
}
URL.createObjectURL = function(blob) {
var
type = blob.type
, data_URI_header
;
if (type === null) {
type = "application/octet-stream";
}
if (blob instanceof FakeBlob) {
data_URI_header = "data:" + type;
if (blob.encoding === "base64") {
return data_URI_header + ";base64," + blob.data;
} else if (blob.encoding === "URI") {
return data_URI_header + "," + decodeURIComponent(blob.data);
} if (btoa) {
return data_URI_header + ";base64," + btoa(blob.data);
} else {
return data_URI_header + "," + encodeURIComponent(blob.data);
}
} else if (real_create_object_URL) {
return real_create_object_URL.call(real_URL, blob);
}
};
URL.revokeObjectURL = function(object_URL) {
if (object_URL.substring(0, 5) !== "data:" && real_revoke_object_URL) {
real_revoke_object_URL.call(real_URL, object_URL);
}
};
FBB_proto.append = function(data/*, endings*/) {
var bb = this.data;
// decode data to a binary string
if (Uint8Array && (data instanceof ArrayBuffer || data instanceof Uint8Array)) {
var
str = ""
, buf = new Uint8Array(data)
, i = 0
, buf_len = buf.length
;
for (; i < buf_len; i++) {
str += String.fromCharCode(buf[i]);
}
bb.push(str);
} else if (get_class(data) === "Blob" || get_class(data) === "File") {
if (FileReaderSync) {
var fr = new FileReaderSync;
bb.push(fr.readAsBinaryString(data));
} else {
// async FileReader won't work as BlobBuilder is sync
throw new FileException("NOT_READABLE_ERR");
}
} else if (data instanceof FakeBlob) {
if (data.encoding === "base64" && atob) {
bb.push(atob(data.data));
} else if (data.encoding === "URI") {
bb.push(decodeURIComponent(data.data));
} else if (data.encoding === "raw") {
bb.push(data.data);
}
} else {
if (typeof data !== "string") {
data += ""; // convert unsupported types to strings
}
// decode UTF-16 to binary string
bb.push(unescape(encodeURIComponent(data)));
}
};
FBB_proto.getBlob = function(type) {
if (!arguments.length) {
type = null;
}
return new FakeBlob(this.data.join(""), type, "raw");
};
FBB_proto.toString = function() {
return "[object BlobBuilder]";
};
FB_proto.slice = function(start, end, type) {
var args = arguments.length;
if (args < 3) {
type = null;
}
return new FakeBlob(
this.data.slice(start, args > 1 ? end : this.data.length)
, type
, this.encoding
);
};
FB_proto.toString = function() {
return "[object Blob]";
};
FB_proto.close = function() {
this.size = 0;
delete this.data;
};
return FakeBlobBuilder;
}(view));
view.Blob = function(blobParts, options) {
var type = options ? (options.type || "") : "";
var builder = new BlobBuilder();
if (blobParts) {
for (var i = 0, len = blobParts.length; i < len; i++) {
if (Uint8Array && blobParts[i] instanceof Uint8Array) {
builder.append(blobParts[i].buffer);
}
else {
builder.append(blobParts[i]);
}
}
}
var blob = builder.getBlob(type);
if (!blob.slice && blob.webkitSlice) {
blob.slice = blob.webkitSlice;
}
return blob;
};
var getPrototypeOf = Object.getPrototypeOf || function(object) {
return object.__proto__;
};
view.Blob.prototype = getPrototypeOf(new view.Blob());
}(
typeof self !== "undefined" && self
|| typeof window !== "undefined" && window
|| this
));

View File

@@ -1,131 +0,0 @@
/* eslint-disable */
import './_blob'
import FileSaver from 'file-saver'
import XLSX from 'xlsx'
function generateArray(table) {
var out = [];
var rows = table.querySelectorAll('tr');
var ranges = [];
for (var R = 0; R < rows.length; ++R) {
var outRow = [];
var row = rows[R];
var columns = row.querySelectorAll('td');
for (var C = 0; C < columns.length; ++C) {
var cell = columns[C];
var colspan = cell.getAttribute('colspan');
var rowspan = cell.getAttribute('rowspan');
var cellValue = cell.innerText;
if (cellValue !== "" && cellValue == +cellValue) cellValue = +cellValue;
ranges.forEach(function (range) {
if (R >= range.s.r && R <= range.e.r && outRow.length >= range.s.c && outRow.length <= range.e.c) {
for (var i = 0; i <= range.e.c - range.s.c; ++i) outRow.push(null);
}
});
if (rowspan || colspan) {
rowspan = rowspan || 1;
colspan = colspan || 1;
ranges.push({s: {r: R, c: outRow.length}, e: {r: R + rowspan - 1, c: outRow.length + colspan - 1}});
};
outRow.push(cellValue !== "" ? cellValue : null);
if (colspan) for (var k = 0; k < colspan - 1; ++k) outRow.push(null);
}
out.push(outRow);
}
return [out, ranges];
};
function datenum(v, date1904) {
if (date1904) v += 1462;
var epoch = Date.parse(v);
return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
}
function sheet_from_array_of_arrays(data, opts) {
var ws = {};
var range = {s: {c: 10000000, r: 10000000}, e: {c: 0, r: 0}};
for (var R = 0; R != data.length; ++R) {
for (var C = 0; C != data[R].length; ++C) {
if (range.s.r > R) range.s.r = R;
if (range.s.c > C) range.s.c = C;
if (range.e.r < R) range.e.r = R;
if (range.e.c < C) range.e.c = C;
var cell = {v: data[R][C]};
if (cell.v == null) continue;
var cell_ref = XLSX.utils.encode_cell({c: C, r: R});
if (typeof cell.v === 'number') cell.t = 'n';
else if (typeof cell.v === 'boolean') cell.t = 'b';
else if (cell.v instanceof Date) {
cell.t = 'n';
cell.z = XLSX.SSF._table[14];
cell.v = datenum(cell.v);
}
else cell.t = 's';
ws[cell_ref] = cell;
}
}
if (range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range);
return ws;
}
function Workbook() {
if (!(this instanceof Workbook)) return new Workbook();
this.SheetNames = [];
this.Sheets = {};
}
function s2ab(s) {
var buf = new ArrayBuffer(s.length);
var view = new Uint8Array(buf);
for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
return buf;
}
export function export_table_to_excel(id) {
var theTable = document.getElementById(id);
var oo = generateArray(theTable);
var ranges = oo[1];
var data = oo[0];
var ws_name = "SheetJS";
var wb = new Workbook(), ws = sheet_from_array_of_arrays(data);
ws['!merges'] = ranges;
wb.SheetNames.push(ws_name);
wb.Sheets[ws_name] = ws;
var wbout = XLSX.write(wb, {bookType: 'xlsx', bookSST: false, type: 'binary'});
FileSaver.saveAs(new Blob([s2ab(wbout)], {type: "application/octet-stream"}), "test.xlsx")
}
export function export_json_to_excel(th, jsonData, defaultTitle) {
var data = jsonData;
data.unshift(th);
var ws_name = "SheetJS";
var wb = new Workbook(), ws = sheet_from_array_of_arrays(data);
const colWidth = data.map(row => row.map(val => {
if (val == null) {
return {'wch': 10};
}
else if (val.toString().charCodeAt(0) > 255) {
return {'wch': val.toString().length * 2};
} else {
return {'wch': val.toString().length};
}
}))
let result = colWidth[0];
for (let i = 1; i < colWidth.length; i++) {
for (let j = 0; j < colWidth[i].length; j++) {
if (result[j]['wch'] < colWidth[i][j]['wch']) {
result[j]['wch'] = colWidth[i][j]['wch'];
}
}
}
ws['!cols'] = result;
wb.SheetNames.push(ws_name);
wb.Sheets[ws_name] = ws;
var wbout = XLSX.write(wb, {bookType: 'xlsx', bookSST: false, type: 'binary'});
var title = defaultTitle || 'table'
FileSaver.saveAs(new Blob([s2ab(wbout)], {type: "application/octet-stream"}), title + ".xlsx")
}

View File

@@ -1,71 +0,0 @@
/* eslint-disable */
// 库
import Csv from './_csv'
import ExportCsv from './_export-csv'
import FileSaver from 'file-saver'
import * as Excel from './_export2Excel'
export default {
install (Vue, options) {
Vue.prototype.$export = {
// 导出 csv
csv (params) {
return new Promise((resolve, reject) => {
// 默认值
const paramsDefault = {
columns: [],
data: [],
title: 'table',
noHeader: false
}
// 合并参数
const _params = Object.assign({}, paramsDefault, params)
// 生成数据
const data = Csv(_params.columns, _params.data, params, _params.noHeader)
// 下载数据
ExportCsv.download(_params.title, data)
// 完成
resolve()
})
},
// 导出 excel
excel (params) {
return new Promise((resolve, reject) => {
// 默认值
const paramsDefault = {
columns: [],
data: [],
title: 'table'
}
// 合并参数
const _params = Object.assign({}, paramsDefault, params)
// 从参数中派生数据
const header = _params.columns.map(e => e.label)
const data = _params.data.map(row => _params.columns.map(col => row[col.prop]))
// 导出
Excel.export_json_to_excel(header, data, _params.title)
// 完成
resolve()
})
},
// 导出 文本文档
txt (params) {
return new Promise((resolve, reject) => {
// 默认值
const paramsDefault = {
text: '',
title: '文本'
}
// 合并参数
const _params = Object.assign({}, paramsDefault, params)
// 导出
const blob = new Blob([_params.text], {type: 'text/plain;charset=utf-8'})
FileSaver.saveAs(blob, _params.title + '.txt')
// 完成
resolve()
})
}
}
}
}

View File

@@ -1,62 +0,0 @@
/* eslint-disable */
// 库
import papa from 'papaparse'
import xlsx from 'xlsx'
export default {
install (Vue, options) {
Vue.prototype.$import = {
// 导入 csv
csv (file) {
return new Promise((resolve, reject) => {
papa.parse(file, {
header: true,
skipEmptyLines: true,
complete: (results, file) => {
resolve(results)
}
})
})
},
// 导入 xlsx
xlsx (file) {
return new Promise((resolve, reject) => {
const reader = new FileReader()
const fixdata = data => {
let o = ''
let l = 0
const w = 10240
for (; l < data.byteLength / w; ++l) o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w, l * w + w)))
o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w)))
return o
}
const getHeaderRow = sheet => {
const headers = []
const range = xlsx.utils.decode_range(sheet['!ref'])
let C
const R = range.s.r
for (C = range.s.c; C <= range.e.c; ++C) {
var cell = sheet[xlsx.utils.encode_cell({ c: C, r: R })]
var hdr = 'UNKNOWN ' + C
if (cell && cell.t) hdr = xlsx.utils.format_cell(cell)
headers.push(hdr)
}
return headers
}
reader.onload = e => {
const data = e.target.result
const fixedData = fixdata(data)
const workbook = xlsx.read(btoa(fixedData), { type: 'base64' })
const firstSheetName = workbook.SheetNames[0]
const worksheet = workbook.Sheets[firstSheetName]
const header = getHeaderRow(worksheet)
const results = xlsx.utils.sheet_to_json(worksheet)
resolve({header, results})
}
reader.readAsArrayBuffer(file)
})
}
}
}
}

View File

@@ -1,18 +0,0 @@
export default {
install (Vue, options) {
// 打印log
// 如果只有一个参数 就只简单打印第一个参数
// 如果有大于一个参数 第一个参数会当做是分组的名称
Vue.prototype.$log = (arg1 = 'log', ...logs) => {
if (logs.length === 0) {
console.log(arg1)
} else {
console.group(arg1)
logs.forEach(e => {
console.log(e)
})
console.groupEnd()
}
}
}
}

View File

@@ -1,8 +0,0 @@
export default {
install (Vue, options) {
// 打开一个url
Vue.prototype.$open = (url = 'https://github.com/d2-projects') => {
window.open(url)
}
}
}

View File

@@ -1,76 +0,0 @@
<template>
<button class="v-bt-button" @click="handleClick">
<span v-if="type === 'confirm'" class="i con-i"><i class="l con-i-l1 l1"></i><i class="l con-i-l2 l2"></i></span>
<span v-else class="i can-i"><i class="l can-i-l1 l1"></i><i class="l can-i-l2 l2"></i></span>
</button>
</template>
<script>
export default {
name: 'Button',
props: {
type: String
},
methods: {
handleClick (e) {
this.$emit('click', e);
}
}
};
</script>
<style lang="less">
@import '../styles/common.less';
.v-bt-button{
padding: 2px 7px;
width: 20px;
background: transparent;
border: none;
vertical-align: middle;
outline: none;
transform: translateY(3px);
cursor: pointer;
&:hover{
.l{
background: @basic-blue;
transition: background .2s ease;
}
}
.i{
position: relative;
display: inline-block;
width: 10px;
height: 10px;
i{
display: inline-block;
position: absolute;
left: 0px;
top: 0px;
background: #000000;
border-radius: 1px;
height: 2px;
}
}
.l{
transition: background .2s ease;
}
.con-i{
&-l1{
width: 7px;
transform: rotateZ(45deg) translate(3px, 0px);
}
&-l2{
width: 10px;
transform: rotateZ(-45deg) translate(5px, 4px);
}
}
.can-i{
&-l1{
width: 12px;
transform: rotateZ(45deg);
}
&-l2{
width: 12px;
transform: rotateZ(-45deg);
}
}
}
</style>

View File

@@ -1,55 +0,0 @@
import Input from './input.vue';
import Button from './button.vue';
export default (h, {row, col, value, beforeSave, initRowIndex}, table) => {
return h('div', {
'class': 'edit-item-con'
}, [
h(Input, {
'class': 'edit-item-input',
props: {
value: value
},
on: {
input (res) {
table.editContent = res;
}
}
}),
h('div', {
'class': 'edit-item-btn-con'
}, [
h(Button, {
'class': 'edit-btn',
props: {
type: 'confirm'
},
on: {
click () {
const params = {
row,
col,
value: table.editContent,
initRowIndex
};
if (beforeSave({ row, col, value, initRowIndex })) {
table.$emit('on-success-save', params);
} else {
table.$emit('on-fail-save', params);
}
}
}
}),
h(Button, {
'class': 'edit-btn',
props: {
type: 'cancel'
},
on: {
click () {
table.$emit('on-cancel-edit');
}
}
})
])
]);
};

View File

@@ -1,46 +0,0 @@
<template>
<input class="v-bt-input" :value="value" @input="handleInput" />
</template>
<script>
export default {
name: 'Input',
props: {
value: [String, Number]
},
methods: {
handleInput (e) {
this.$emit('input', e.target.value);
}
},
mounted () {
this.$emit('input', this.value);
}
};
</script>
<style lang="less">
@import '../styles/common.less';
.v-bt-input{
box-sizing: border-box;
width: 100%;
height: 32px;
line-height: 1.5;
padding: 4px 7px;
font-size: 12px;
border: 1px solid #dddee1;
border-radius: 4px;
color: #495060;
background-color: #fff;
background-image: none;
position: relative;
cursor: text;
outline: none;
transition: border .2s ease-in-out,background .2s ease-in-out,box-shadow .2s ease-in-out,-webkit-box-shadow .2s ease-in-out;
&:hover{
border-color: @basic-blue;
}
&:focus{
border-color: @basic-blue;
box-shadow: 0 0 0 2px rgba(45,140,240,.2)
}
}
</style>

View File

@@ -1,209 +0,0 @@
<template>
<div class="v-bt-item-table">
<table v-show="showTable && fixedCol >= 0" @paste="handlePaste" :class="['v-bt-data-table', 'v-bt-fixed-table', showFixedBoxShadow ? 'box-shadow' : '']" cellspacing="0" cellpadding="0" border="0">
<colgroup>
<col
v-if="i <= fixedCol"
:width="width" v-for="(width, i) in widthArr"
:key="'colgroup-fixed-' + i"
>
</colgroup>
<tbody>
<tr
v-for="(tr, index) in itemData"
:key="index"
:style="{background: currentMouseEnterIndex === index && canSelectText ? '#ebf7ff' : ''}"
:class="[stripe && (indexBase + index) % 2 !== 0 ? 'stripe-gray' : '', tr.className, currentScrollToRowIndex === indexBase + index ? 'scroll-to-row-tip' : '']"
@click="handleClickTr(indexBase + index)"
@mouseenter.stop="handleMouseIn(index)"
@mouseleave.stop="handleMouseLeave">
<td v-if="showIndex" :class="['v-bt-cell', 'v-bt-data-table-center']">
<render-dom :render="indexRender" :back-value="(indexBase + index)"></render-dom>
</td>
<td
v-if="i <= fixedColCom"
:data-row="indexBase + index"
:data-col="i"
@click="handleClickTd(indexBase + index, i)"
@dblclick="handleDblclickTd(indexBase + index, i, typeof td === 'object' ? td.value : td)"
v-for="(td, i) in tr"
:class="['v-bt-cell',
setAlign(i),
typeof td === 'object' ? td.className : '',
getSelectCellClasses(indexBase + index, i)
]"
:style="rowStyles" :key="i">
<template v-if="!canEdit || (canEdit && `${indexBase + index}-${i}` !== edittingTd)">
<div v-if="!showCellRender[showIndex ? (i + 1) : i]" class="v-bt-cell">{{ typeof td === 'object' ? td.value : td }}</div>
<template v-else>
<render-dom :render="showCellRender[showIndex ? (i + 1) : i]" :back-value="{row: indexBase + index, col: i}"></render-dom>
</template>
</template>
<render-dom v-else :render="editCellRender" :back-value="{row: indexBase + index, col: i, value: typeof td === 'object' ? td.value : td, beforeSave}"></render-dom>
</td>
</tr>
</tbody>
</table>
<table v-show="showTable" @paste="handlePaste" ref="itemTable" class="v-bt-data-table v-bt-content-table" :style="{position: fixedCol < 0 ? '' : 'absolute'}" cellspacing="0" cellpadding="0" border="0" width="100%">
<colgroup>
<col
:width="width" v-for="(width, i) in widthArr"
:key="'colgroup-' + i"
>
</colgroup>
<tbody>
<tr
v-for="(tr, index) in itemData"
:key="index"
@click="handleClickTr(indexBase + index)"
@mouseenter.stop="handleMouseIn(index)"
@mouseleave.stop="handleMouseLeave"
:style="{background: currentMouseEnterIndex === index && canSelectText ? '#ebf7ff' : ''}"
:class="[stripe && (indexBase + index) % 2 !== 0 ? 'stripe-gray' : '', tr.className, currentScrollToRowIndex === indexBase + index ? 'scroll-to-row-tip' : '']">
<td v-if="showIndex" :class="['v-bt-cell', 'v-bt-data-table-center']">
<render-dom v-if="fixedCol < 0" :render="indexRender" :back-value="(indexBase + index)"></render-dom>
</td>
<td
v-for="(td, i) in tr"
:data-row="indexBase + index"
:data-col="i"
@click="handleClickTd(indexBase + index, i)"
@dblclick="handleDblclickTd(indexBase + index, i, typeof td === 'object' ? td.value : td)"
:class="['v-bt-cell',
setAlign(i),
typeof td === 'object' ? td.className : '',
getSelectCellClasses(indexBase + index, i)
]"
:style="rowStyles"
:key="i">
<template v-if="!canEdit || (canEdit && `${indexBase + index}-${i}` !== edittingTd)">
<div v-if="(!showCellRender[showIndex ? (i + 1) : i]) && (i >= fixedCol)" class="v-bt-cell">{{ typeof td === 'object' ? td.value : td }}</div>
<template v-else-if="i >= fixedCol">
<render-dom :render="showCellRender[showIndex ? (i + 1) : i]" :back-value="{row: indexBase + index, col: i}"></render-dom>
</template>
</template>
<render-dom v-else :render="editCellRender" :back-value="{row: indexBase + index, col: i, value: typeof td === 'object' ? td.value : td, beforeSave, initRowIndex: tr.initRowIndex}"></render-dom>
</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
import renderDom from './renderDom';
export default {
name: 'ItemTable',
components: {
renderDom
},
data () {
return {
prefix: 'v-bt-data-table',
tableWidth: 0,
currentMouseEnterIndex: -1,
editInputValue: ''
};
},
props: {
times: Number,
tableIndex: Number,
itemData: Array,
rowStyles: Object,
widthArr: Array,
columns: Array,
itemNum: Number,
showIndex: Boolean,
indexRender: Function,
stripe: Boolean,
fixedCol: Number,
currentScrollToRowIndex: Number,
canEdit: Boolean,
edittingTd: String,
startEditType: String,
showFixedBoxShadow: Boolean,
editCellRender: Function,
beforeSave: Function,
canSelectText: Boolean,
startSelect: Object,
endSelect: Object,
disabledHover: Boolean
},
computed: {
showTable () {
return this.itemData.length > 0;
},
indexBase () {
return this.times * this.itemNum * 3 + this.itemNum * (this.tableIndex - 1);
},
showCellRender () {
return this.columns.map(item => {
return item.cellRender ? item.cellRender : undefined;
});
},
baseIndex () {
return this.showIndex ? 1 : 0;
},
fixedColCom () {
return this.showIndex ? (this.fixedCol - 1) : this.fixedCol;
}
},
methods: {
setAlign (i) {
let columns = this.columns[i + this.baseIndex];
if (!columns) return;
let col = columns;
return this.prefix + '-' + col.align;
},
backValue (row, col) {
return {
row: row,
col: col
};
},
handleMouseIn (index) {
if (!this.disabledHover) return;
this.currentMouseEnterIndex = index;
},
handleMouseLeave () {
this.currentMouseEnterIndex = -1;
},
handleClickTr (index) {
this.$emit('on-click-tr', index);
},
handleClickTd (row, col) {
this.$emit('on-click-td', { row, col });
},
editCell (row, col) {
this.$emit('on-edit-cell', row, col);
},
handleDblclickTd (row, col, value) {
this.editInputValue = value;
if (this.canEdit && this.startEditType === 'dblclick') this.editCell(row, col);
},
getSelectCellClasses (row, col) {
let startSelect = this.startSelect;
let endSelect = this.endSelect;
let startRow = parseInt(startSelect['row']);
let endRow = parseInt(endSelect['row']);
let startCol = parseInt(startSelect['col']);
return [
((startRow === row) && startCol === col) ? 'start-select-cell' : '',
((endRow === row) && endSelect['col'] === col) ? 'end-select-cell' : '',
((startRow === row) && endSelect['col'] === col) ? 'right-top-select-cell' : '',
((endRow === row) && startCol === col) ? 'left-bottom-select-cell' : '',
((startRow === row) && col > startCol && col < endSelect['col']) ? 'top-center-select-cell' : '',
((endRow === row) && col > startCol && col < endSelect['col']) ? 'bottom-center-select-cell' : '',
(startCol === col && row > startRow && row < endRow) ? 'left-center-select-cell' : '',
(endSelect['col'] === col && row > startRow && row < endRow) ? 'right-center-select-cell' : ''
];
},
handlePaste (e) {
const data = e.clipboardData.getData('text/plain');
const rowsData = data.split((/[\n\u0085\u2028\u2029]|\r\n?/g)).map((row) => {
return row.split('\t');
});
this.$emit('on-paste', rowsData);
}
}
};
</script>

View File

@@ -1,11 +0,0 @@
export default {
name: 'RenderCell',
functional: true,
props: {
render: Function,
backValue: [Number, Object]
},
render: (h, ctx) => {
return ctx.props.render(h, ctx.props.backValue, ctx.parent);
}
};

View File

@@ -1,44 +0,0 @@
<template>
<span class="sort-button-wrapper" @click="handleSort">
<i data-sort-btn="up" :class="[currentActiveColSort && currentSortType === 'up' ? 'sort-button-item-up-active' : '']" class="sort-button-item sort-button-item-up"></i>
<i data-sort-btn="down" :class="[currentActiveColSort && currentSortType === 'down' ? 'sort-button-item-down-active' : '']" class="sort-button-item sort-button-item-down"></i>
</span>
</template>
<script>
import { attr } from '../util';
export default {
name: 'sortButton',
data () {
return {
sortingType: ''
};
},
props: {
colIndex: Number,
currentSortColIndex: Number,
currentSortType: String
},
computed: {
currentActiveColSort () {
return this.colIndex === this.currentSortColIndex;
}
},
watch: {
currentSortType (type) {
if (this.currentSortColIndex === this.colIndex) this.sortingType = type;
}
},
methods: {
handleSort (e) {
const sortType = attr(e.target, 'data-sort-btn');
if (this.sortingType === sortType) {
this.sortingType = '';
this.$emit('on-cancel-sort');
} else {
this.sortingType = sortType;
this.$emit('on-sort', this.colIndex, sortType);
}
}
}
};
</script>

View File

@@ -1,8 +0,0 @@
import bigdataTable from './vue-bigdata-table.vue';
const install = (Vue, opts = {}) => {
Vue.component('bigdataTable', bigdataTable);
};
if (typeof window !== 'undefined' && window.Vue) {
install(window.Vue);
}
export default Object.assign(bigdataTable, {install});

View File

@@ -1,199 +0,0 @@
import ItemTable from '../components/item-table.vue';
import { iteratorByTimes, getHeaderWords } from '../util';
export default {
data () {
return {
times0: 0, // 当前是第几轮
times1: 0,
times2: -1,
table1Data: [],
table2Data: [],
table3Data: [],
currentIndex: 0, // 当前展示的表格是第几个
itemNum: 0, // 一块数据显示的数据条数
timer: null,
scrollLeft: 0,
insideTableData: [],
initTableData: [] // 初始表格数据,用于恢复搜索和筛选
};
},
computed: {
cellNum () { // 表格列数
return this.columnsHandled.length;
},
columnsHandled () {
let columns = [...this.columns];
if (this.colNum > this.columns.length) {
let colLength = this.colNum - this.columns.length;
let headerWordsArr = getHeaderWords(colLength);
iteratorByTimes(colLength, (i) => {
columns.push({
title: headerWordsArr[i]
});
});
}
if (this.showIndex) {
columns.unshift({
title: 'No',
align: 'center',
width: this.indexWidthInside
});
}
return columns;
}
},
watch: {
scrollTop (top) {
this.currentIndex = parseInt((top % (this.moduleHeight * 3)) / this.moduleHeight);
this.$nextTick(() => {
this.setTopPlace();
});
}
},
methods: {
getComputedTableDataIndex (colIndex) {
return this.showIndex ? (colIndex - 1) : colIndex;
},
handleScroll (e) {
const ele = e.srcElement || e.target;
const { scrollTop, scrollLeft } = ele;
this.scrollLeft = scrollLeft;
this.scrollTop = scrollTop;
},
setTableData () {
const count1 = this.times0 * this.itemNum * 3;
this.table1Data = this.insideTableData.slice(count1, count1 + this.itemNum);
const count2 = this.times1 * this.itemNum * 3;
this.table2Data = this.insideTableData.slice(count2 + this.itemNum, count2 + this.itemNum * 2);
const count3 = this.times2 * this.itemNum * 3;
this.table3Data = this.insideTableData.slice(count3 + this.itemNum * 2, count3 + this.itemNum * 3);
},
getTables (h) {
let table1 = this.getItemTable(h, this.table1Data, 1);
let table2 = this.getItemTable(h, this.table2Data, 2);
let table3 = this.getItemTable(h, this.table3Data, 3);
if (this.currentIndex === 0) return [table1, table2, table3];
else if (this.currentIndex === 1) return [table2, table3, table1];
else return [table3, table1, table2];
},
renderTable (h) {
return h('div', {
style: this.tableWidthStyles
}, this.getTables(h));
},
getItemTable (h, data, index) {
return h(ItemTable, {
props: {
times: this['times' + (index - 1)],
tableIndex: index,
itemData: data,
itemNum: this.itemNum,
rowStyles: this.rowStyles,
widthArr: this.colWidthArr,
columns: this.columnsHandled,
showIndex: this.showIndex,
indexRender: this.indexRender,
stripe: this.stripe,
fixedCol: this.fixedCol,
currentScrollToRowIndex: this.currentScrollToRowIndex,
canEdit: this.canEdit,
edittingTd: this.edittingTd,
startEditType: this.startEditType,
showFixedBoxShadow: this.showFixedBoxShadow,
editCellRender: this.editCellRender,
beforeSave: this.beforeSave,
canSelectText: this.canSelectText,
startSelect: this.startSelect,
endSelect: this.endSelect,
disabledHover: this.disabledHover
},
on: {
'on-click-tr': (index) => {
this.$emit('on-click-tr', index);
},
'on-click-td': (params) => {
this.$emit('on-click-td', params);
},
'on-edit-cell': (row, col) => {
this.edittingTd = `${row}-${col}`;
},
'on-success-save': ({ row, col, value, initRowIndex }) => {
let data = [...this.value];
data[initRowIndex][col] = value;
this.$emit('input', data);
this.$emit('on-success-save', { row, col, value, initRowIndex });
this.edittingTd = '';
},
'on-fail-save': ({ row, col, value, initRowIndex }) => {
this.$emit('on-fail-save', { row, col, value, initRowIndex });
},
'on-cancel-edit': () => {
this.edittingTd = '';
},
'on-paste': (data) => {
if (!this.paste) return;
let value = [...this.value];
let rowLength = data.length;
let startSelect = this.startSelect;
let endSelect = this.endSelect;
let startRow = startSelect.row;
let startCol = startSelect.col;
let endRow = endSelect.row;
let endCol = endSelect.col;
let selectRow = endRow - startRow + 1;
let selectCol = endCol - startCol + 1;
// let lastColLength = value[0].length - startCol;
// let lastRowLength = value.length - startRow;
if (rowLength === 0) return;
let colLength = data[0].length;
if (colLength === 0) return;
// 使用复制的数据替换原数据
for (let r = 0; r < rowLength && r < selectRow; r++) {
for (let c = 0; c < colLength && c < selectCol; c++) {
let valueRow = startRow + r;
let valueCol = startCol + c;
if (typeof value[valueRow][valueCol] === 'object') {
value[valueRow][valueCol].value = data[r][c];
} else {
value[valueRow][valueCol] = data[r][c];
}
}
}
// for (let r = startRow; r < selectRow; r++) {
// for (let c = startCol; c < selectCol; c++) {
// //
// }
// }
this.$emit('input', value);
this.$emit('on-paste', data);
this._tableResize();
}
},
key: 'table-item-key' + index,
ref: 'itemTable' + index,
attrs: {
'data-index': index
}
});
},
_scrollToIndexRow (index) {
index = parseInt(index);
if (isNaN(index) || index >= this.insideTableData.length || index < 0) return;
let scrollTop = index * this.itemRowHeight;
this.$refs.outer.scrollTop = scrollTop;
this.currentScrollToRowIndex = index;
clearTimeout(this.timer);
this.timer = setTimeout(() => {
this.currentScrollToRowIndex = -1;
}, 1800);
},
// 给表格数据添加行号,用于排序后正确修改数据
setIndex (tableData) {
return tableData.map((item, i) => {
let row = item;
row.initRowIndex = i;
return row;
});
}
}
};

View File

@@ -1,77 +0,0 @@
import { findNodeUpper, on, off, attr } from '../util';
export default {
data () {
return {
edittingTd: '', // 正在编辑的单元格的行号和列号拼接的字符串 `${row}-${col}`
editContent: '', // 用来保存编辑的内容
selectCellsStart: {}, // 编辑模式下可选中多行多列,此用来保存其实单元格行列号
selectCellsEnd: {},
selectTotalColStartIndex: -1, // 选取整列起始序列号
selectTotalColEndIndex: -1
};
},
computed: {
startSelect () {
return {
row: Math.min(this.selectCellsStart.row, this.selectCellsEnd.row),
col: Math.min(this.selectCellsStart.col, this.selectCellsEnd.col)
};
},
endSelect () {
return {
row: Math.max(this.selectCellsStart.row, this.selectCellsEnd.row),
col: Math.max(this.selectCellsStart.col, this.selectCellsEnd.col)
};
}
},
methods: {
_editCell (row, col) {
if (!this.canEdit || row < 0 || row > this.insideTableData.length || col < 0 || col > this.columns.length || this.edittingTd === `${row}-${col}`) return;
if (parseInt(this.edittingTd.split('-')[0]) !== row) this.scrollToRow(row);
this.edittingTd = `${row}-${col}`;
},
getCurrentTd (e) {
return e.target.tagName === 'TD' ? e.target : findNodeUpper(e.target, 'td');
},
handleMousedownOnTable (e) {
if (e.button !== 0 || (!this.paste && !this.selectable)) return;
let currentTd = this.getCurrentTd(e);
this.selectCellsStart = {
row: attr(currentTd, 'data-row'),
col: attr(currentTd, 'data-col')
};
this.selectCellsEnd = {
row: attr(currentTd, 'data-row'),
col: attr(currentTd, 'data-col')
};
this.canSelectText = false;
on(document, 'mousemove', this.handleMoveOnTable);
on(document, 'mouseup', this.handleUpOnTable);
},
handleMoveOnTable (e) {
if (!(e.target.tagName === 'TD' || findNodeUpper(e.target, 'td'))) return;
let currentTd = this.getCurrentTd(e);
this.selectCellsEnd = {
row: attr(currentTd, 'data-row'),
col: attr(currentTd, 'data-col')
};
},
handleUpOnTable (e) {
if (!this.paste && !this.selectable) return;
this.canSelectText = true;
this.handleMoveOnTable(e);
off(document, 'mousemove', this.handleMoveOnTable);
off(document, 'mouseup', this.handleUpOnTable);
this.$emit('on-select-cells', {
start: {
row: this.startSelect.row,
col: this.startSelect.col
},
end: {
row: this.endSelect.row,
col: this.endSelect.col
}
});
}
}
};

View File

@@ -1,31 +0,0 @@
export default {
methods: {
_createEmptyData () {
// this.$nextTick(() => {
let rowNum = this.rowNum;
let colNum = this.colNum;
if (this.rowNum && this.colNum) {
console.log(this.value.length, this.rowNum, this.colNum);
let valueRowNum = this.value.length;
let valueColNum = this.value[0] ? this.value[0].length : 0;
let totalRowNum = valueRowNum + rowNum;
let totalColNum = valueColNum + colNum;
let value = [...this.value];
console.log(totalRowNum, valueRowNum);
for (let r = valueRowNum; r < totalRowNum; r++) {
value.push([]);
for (let c = valueColNum; c < totalColNum; c++) {
value[r].push('');
}
}
// this.
console.log(value);
this.$emit('input', value);
// this.$nextTick(() => {
// this._tableResize();
// })
}
// });
}
}
};

View File

@@ -1,64 +0,0 @@
import { findNodeUpper, attr } from '../util';
export default {
data () {
return {
isOnCellEdge: false, // 鼠标是否在表头的两个单元格之间的边框上
canResizeCell: false,
initCellX: 0, // 用于计算鼠标移动的距离
scrollLeft: 0,
colIndex: 0, // 在表头上移动时鼠标所在列的序号,
atLeftGivenArea: false, // 是否在表头单元格指定区域(距左侧)
atRightGivenArea: false // 是否在表头单元格指定区域(距右侧)
};
},
methods: {
handleMousemove (e) {
let cell = e.srcElement.tagName.toUpperCase() === 'TH' ? e.srcElement : findNodeUpper(e.srcElement, 'th');
let cellDomRect = cell.getBoundingClientRect();
let atLeft = (e.pageX - cellDomRect.left) < (cellDomRect.width / 2);
let atLeftGivenArea = (cellDomRect.left + this.atLeftCellPosi) >= e.pageX;
let atRightGivenArea = (cellDomRect.right - e.pageX) <= this.atRightCellPosi;
let cellIndex = parseInt(attr(cell, 'data-index')); // 当前单元格的序号
if (atLeft && cellIndex !== 0) {
this.isOnCellEdge = (e.pageX - cellDomRect.left) <= 1 && cellIndex - 1 !== this.fixedCol;
} else if (!atLeft && cellIndex !== this.cellNum - 1) {
this.isOnCellEdge = (cellDomRect.right - e.pageX) <= 1 && cellIndex !== this.fixedCol;
}
e.atRightGivenArea = atRightGivenArea;
e.atLeftGivenArea = atLeftGivenArea;
this.atRightGivenArea = atRightGivenArea;
this.atLeftGivenArea = atLeftGivenArea;
let index = 0; // 调整表格列宽的左侧的表格的序列
e.colIndex = cellIndex;
this.colIndex = cellIndex;
this.$emit('on-moving-on-header', e);
if (this.canResizeCell) {
if (atLeft) {
index = cellIndex - 1;
} else {
index = cellIndex;
}
if (index === this.fixedCol) return;
let widthLeft = this.widthArr[index] + e.pageX - this.initCellX;
let widthRight = this.widthArr[index + 1] + this.initCellX - e.pageX;
this.widthArr.splice(index, 2, widthLeft, widthRight);
this.initCellX = e.pageX;
}
},
handleMousedown (e) {
e.colIndex = this.cellIndex;
this.$emit('on-mousedown-on-header', e);
if (this.isOnCellEdge) {
this.canResizeCell = true;
this.initCellX = e.pageX;
}
},
canNotMove (e) {
this.canResizeCell = false;
e.colIndex = this.colIndex;
e.atLeftGivenArea = this.atLeftGivenArea;
e.atRightGivenArea = this.atRightGivenArea;
this.$emit('on-mouseup-on-header', e);
}
}
};

View File

@@ -1,8 +0,0 @@
import headerMove from './header-move';
import styleComputed from './style-compute';
import dataHandle from './data-handle';
import edit from './edit';
import emptyTable from './empty-table';
import sort from './sort';
export default [ headerMove, styleComputed, dataHandle, edit, emptyTable, sort ];

View File

@@ -1,40 +0,0 @@
import { sortArr, sortDesArr } from '../util';
export default {
data () {
return {
sortedByColIndex: -1,
sortedType: ''
};
},
methods: {
showSortBtn (colIndex) {
const sortable = this.sortable ? true : this.sortIndex !== undefined;
return (sortable && !(this.showIndex && colIndex === 0) && (typeof this.sortIndex === 'number' ? colIndex <= this.sortIndex : this.sortIndex.indexOf(colIndex) >= 0)) || this.columnsHandled[colIndex].sortable;
},
handleSort (colIndex, sortType) {
this.sortedByColIndex = colIndex;
this.sortedType = sortType;
let valueArr = [...this.value];
colIndex = this.showIndex ? colIndex - 1 : colIndex;
if (sortType === 'up') {
sortArr(valueArr, colIndex);
} else {
sortDesArr(valueArr, colIndex);
}
this.insideTableData = [...valueArr];
},
handleCancelSort () {
this.sortedByColIndex = -1;
this.sortedType = '';
this.insideTableData = [...this.value];
},
initSort () {
if (this.defaultSort) {
const colIndex = parseInt(Object.keys(this.defaultSort)[0]);
if (!(colIndex || colIndex === 0)) return;
const sortType = this.defaultSort[colIndex];
this.handleSort(colIndex, sortType);
}
}
}
};

View File

@@ -1,177 +0,0 @@
import { getScrollbarWidth } from '../util';
export default {
data () {
return {
wrapperHeight: 0,
scrollTop: 0,
moduleHeight: 0, // 三个tr块中的一块的高度
topPlaceholderHeight: 0, // 顶部占位容器高度
tableWidth: 0,
widthArr: [], // 用于给数据表格传递列宽
totalRowHeight: 0, // 如果全量渲染应该是多高,用于计算占位
currentScrollToRowIndex: -1, // 当前跳转到的行号,用于做闪烁提示
canSelectText: true, // 用于控制是否可选中表格文字
indexWidthInside: 0,
outerWidth: 0, // 外面容器宽度
oldTableWidth: 0 // 旧的表格宽度,用于重新计算列宽
};
},
computed: {
fixedColCom () {
return this.showIndex ? (this.fixedCol + 1) : this.fixedCol;
},
wrapperClasses () {
return [
this.prefix,
this.fixed ? `${this.prefix}-fixed` : ''
];
},
headerStyle () {
return {
height: this.headerHeight + 'px',
transform: 'translateX(0)'
};
},
showFixedBoxShadow () {
return this.scrollLeft !== 0;
},
tableWidthStyles () {
return {width: this.tableWidth + 'px'};
},
rowStyles () {
return this.rowHeight !== undefined ? {height: `${this.rowHeight}px`} : {};
},
placeholderHeight () {
return this.totalRowHeight - this.moduleHeight * 3; // 占位容器的总高度(上 + 下)
},
bottomPlaceholderHeight () {
return (this.placeholderHeight - this.topPlaceholderHeight) < 0 ? 0 : this.placeholderHeight - this.topPlaceholderHeight;
},
itemRowHeight () {
return this.rowHeight === undefined ? 48 : this.rowHeight;
},
colWidthArr () {
let len = this.cellNum;
let colWidthArr = [];
if (this.fixedWrapperWidth) {
let width = this.outerWidth;
let num = this.cellNum;
if (this.showIndex) {
colWidthArr.push(this.indexWidth);
width -= this.indexWidth;
num -= 1;
}
let i = -1;
let itemColWidth = width / num;
while (++i < num) {
colWidthArr.push(itemColWidth);
}
} else {
let i = 0;
let hasWidthCellCount = 0; // 统计设置了width的列的数量从而为没有设置width的列分配宽度
let noWidthCellIndexArr = []; // 没有设置宽度的列的序列
let hasWidthCellTotalWidth = 0; // 设置了width的列一共多宽
while (i < len) {
if (this.columnsHandled[i].width) {
hasWidthCellCount++;
hasWidthCellTotalWidth += this.columnsHandled[i].width;
colWidthArr.push(this.columnsHandled[i].width);
} else {
noWidthCellIndexArr.push(i);
colWidthArr.push(0);
}
i++;
}
let noWidthCellWidth = (this.tableWidth - hasWidthCellTotalWidth) / (len - hasWidthCellCount);
let w = 0;
let indexArrLen = noWidthCellIndexArr.length;
while (w < indexArrLen) {
colWidthArr[noWidthCellIndexArr[w]] = noWidthCellWidth;
w++;
}
// this.widthArr = colWidthArr;
}
return colWidthArr;
},
cursorOnHeader () {
return this.headerTrStyle.cursor ? this.headerTrStyle.cursor : ((this.isOnCellEdge || this.canResizeCell) ? 'col-resize' : 'default');
}
},
methods: {
_tableResize () {
this.$nextTick(() => {
this.updateHeight();
this.setComputedProps();
let scrollBarWidth = this.totalRowHeight > this.wrapperHeight ? getScrollbarWidth() : 0;
this.outerWidth = this.$refs.outer.offsetWidth - 2 - scrollBarWidth;
let width = this.colWidth * this.columns.length + (this.showIndex ? this.indexWidthInside : 0);
// this.tableWidth = width > this.outerWidth ? width : this.outerWidth;
this.tableWidth = this.fixedWrapperWidth ? this.outerWidth : (width > this.outerWidth ? width : this.outerWidth);
if (width < this.outerWidth) this._setColWidthArr();
this.widthArr = this.colWidthArr;
});
},
updateHeight () {
this.$nextTick(() => {
let wrapperHeight = this.$refs.outer.offsetHeight;
this.itemNum = Math.ceil((wrapperHeight - this.headerHeight) / this.itemRowHeight) + this.appendNum;
this.moduleHeight = this.itemNum * this.itemRowHeight;
this.wrapperHeight = wrapperHeight;
this.setTopPlace();
});
},
setComputedProps () {
const len = this.insideTableData.length;
this.totalRowHeight = len * this.itemRowHeight;
},
setIndexWidth (len) {
let width = 70;
if (len <= 99) {
width = 50;
} else if (len > 99 && len <= 1000) {
width = 60;
} else if (len > 1000 && len <= 10000) {
width = 70;
} else if (len > 10000 && len <= 100000) {
width = 90;
} else {
width = 100;
}
return width;
},
setTopPlace () {
let scrollTop = this.scrollTop;
let t0 = 0;
let t1 = 0;
let t2 = 0;
if (scrollTop > this.moduleHeight) {
switch (this.currentIndex) {
case 0: t0 = parseInt(scrollTop / (this.moduleHeight * 3)); t1 = t2 = t0; break;
case 1: t1 = parseInt((scrollTop - this.moduleHeight) / (this.moduleHeight * 3)); t0 = t1 + 1; t2 = t1; break;
case 2: t2 = parseInt((scrollTop - this.moduleHeight * 2) / (this.moduleHeight * 3)); t0 = t1 = t2 + 1;
}
}
this.times0 = t0;
this.times1 = t1;
this.times2 = t2;
this.topPlaceholderHeight = parseInt(scrollTop / this.moduleHeight) * this.moduleHeight;
this.setTableData();
},
_initM () {
if (this.indexWidth === undefined) this.indexWidthInside = this.setIndexWidth(this.insideTableData.length);
else this.indexWidthInside = this.indexWidth;
this.oldTableWidth = this.colWidthArr.reduce((sum, b) => {
return sum + b;
}, 0);
this.widthArr = this.colWidthArr;
if ((this.colWidth * this.columns.length + (this.showIndex ? this.indexWidthInside : 0)) < this.outerWidth) this._setColWidthArr();
},
_setColWidthArr () {
let widthArr = this.widthArr.map(width => {
return width / this.oldTableWidth * this.tableWidth;
});
this.oldTableWidth = this.tableWidth;
this.widthArr = widthArr;
}
}
};

View File

@@ -1,29 +0,0 @@
@basic-blue: #3695FE;
@border-color: #e9eaec;
@sort-border-width: 4px;
@sort-border-default: #bbbec4;
@sort-border-hover: #495060;
@sort-border-active: @basic-blue;
// 超出用省略号代替
.text-ellipsis{
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
word-break: break-all;
}
// 选择单元格表格
.select-border (@direction) {
border-@{direction}: 1px solid @basic-blue;
}
.no-select{
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.sticky{
position: -webkit-sticky;
position: sticky;
}

View File

@@ -1,232 +0,0 @@
@import './common.less';
@prefix: ~"v-bt";
@keyframes scroll-tip {
0% {
background: #fff;
}
50% {
background: #d0e8ff;
}
}
.@{prefix} {
width: 100%;
box-sizing: border-box;
* {
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
color: #495060;
font-size: 12px;
font-weight: 400;
}
&-outer {
width: 100%;
height: 100%;
overflow: auto;
border: 1px solid @border-color;
box-sizing: border-box;
position: relative;
.@{prefix}-header-wrapper {
box-sizing: border-box;
z-index: 70;
&.header-wrapper-fixed {
.sticky;
}
table {
table-layout: fixed;
height: 100%;
tr th {
border-right: 1px solid @border-color;
border-bottom: 1px solid @border-color;
background: #fff;
.text-ellipsis;
.@{prefix}-header-inside-wrapper {
box-sizing: border-box;
padding: 0 8px;
}
}
}
}
}
&-fixed-header {
.sticky;
transform: translateX(0);
left: 0;
z-index: 110;
transition: box-shadow .2s ease;
&.box-shadow {
box-shadow: 2px 0 6px -2px rgba(0, 0, 0, .2);
transition: box-shadow .2s ease;
}
}
&-wrapper {
width: 100%;
border-bottom: none;
.@{prefix}-content {
width: 100%;
height: auto;
&.noselect-text {
.no-select;
}
}
&:nth-child(2) {
border-top: 1px solid @border-color;
}
&:nth-child(4) {
border-bottom: 1px solid @border-color;
}
.@{prefix}-data-table {
&.@{prefix}-content-table {
left: 0;
top: 0;
}
border-bottom: none;
border-top: none;
table-layout: fixed;
tr {
background: #fff;
&.scroll-to-row-tip {
animation: scroll-tip .6s 3;
}
td{
min-width: 0;
height: 48px;
box-sizing: border-box;
overflow: hidden;
text-overflow: ellipsis;
vertical-align: middle;
border-bottom: 1px solid @border-color;
border-right: 1px solid @border-color;
border-left: 1px solid transparent;
border-top: 1px solid transparent; // 表格选中
.@{prefix}-cell {
box-sizing: border-box;
padding: 0 18px;
.text-ellipsis;
}
.edit-item-con {
width: 100%;
text-align: left;
padding: 0 6px;
box-sizing: border-box;
.edit-item {
&-input {
width: ~"calc(100% - 50px)";
float: left;
}
&-btn-con {
float: left;
.edit-btn {
width: 20px;
margin: 7px 4px 0 0;
}
}
}
}
&.start-select-cell {
.select-border(left);
.select-border(top);
}
&.end-select-cell {
.select-border(right);
.select-border(bottom);
}
&.right-top-select-cell {
.select-border(right);
.select-border(top);
}
&.left-bottom-select-cell {
.select-border(left);
.select-border(bottom);
}
&.top-center-select-cell {
.select-border(top);
}
&.bottom-center-select-cell {
.select-border(bottom);
}
&.left-center-select-cell {
.select-border(left);
}
&.right-center-select-cell {
.select-border(right);
}
}
&.stripe-gray {
background: #f8f8f9;
}
}
&-left {
text-align: left;
}
&-center {
text-align: center;
}
&-right {
text-align: right;
}
}
}
&-fixed {
.@{prefix}-header-wrapper {
top: 0;
left: 0;
box-sizing: border-box;
}
}
&-fixed-table {
.sticky;
left: 0;
z-index: 60;
transition: box-shadow .2s ease;
&.box-shadow {
box-shadow: 2px 0 6px -2px rgba(0, 0, 0, .2);
transition: box-shadow .2s ease;
}
td {
border-right: 1px solid @border-color;
}
}
&-item-table {
position: relative;
}
.sort-button {
&-wrapper {
display: inline-block;
position: relative;
width: 10px;
height: 11px;
transform: translateY(1px);
}
&-item {
position: absolute;
display: inline-block;
width: 0;
height: 0;
border: @sort-border-width solid transparent;
margin: 0;
padding: 0;
cursor: pointer;
transition: border-color .2s ease;
&-up {
top: -4px;
border-bottom: @sort-border-width solid @sort-border-default;
&:hover {
border-bottom: @sort-border-width solid @sort-border-hover;
}
&-active {
border-bottom: @sort-border-width solid @sort-border-active;
}
}
&-down {
bottom: -4px;
border-top: @sort-border-width solid @sort-border-default;
&:hover {
border-top: @sort-border-width solid @sort-border-hover;
}
&-active {
border-top: @sort-border-width solid @sort-border-active;
}
}
}
}
}

View File

@@ -1,136 +0,0 @@
export const findNodeUpper = (ele, tag) => {
if (ele.parentNode) {
if (ele.parentNode.tagName === tag.toUpperCase()) {
return ele.parentNode;
} else {
if (ele.parentNode) return findNodeUpper(ele.parentNode, tag);
else return false;
}
}
};
export const getScrollbarWidth = () => {
let oP = document.createElement('p');
let styles = {
width: '100px',
height: '100px',
overflowY: 'scroll'
};
for (let i in styles) {
oP.style[i] = styles[i];
}
document.body.appendChild(oP);
let scrollbarWidth = oP.offsetWidth - oP.clientWidth;
oP.remove();
return scrollbarWidth;
};
export const createNewArray = (length, content = undefined) => {
let i = -1;
let arr = [];
while (++i < length) {
let con = Array.isArray(content) ? content[i] : content;
arr.push(con);
}
return arr;
};
export const iteratorByTimes = (times, fn) => {
let i = -1;
while (++i < times) {
fn(i);
}
};
export const getHeaderWords = (length) => {
let wordsArr = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
let headerArr = [];
if (length <= 26) {
headerArr = wordsArr.slice(0, length);
} else {
headerArr = [...wordsArr];
let num = length - 26;
let firstWordIndex = 0;
let secondWordIndex = 0;
let i = -1;
while (++i < num) {
firstWordIndex = Math.floor(i / 26);
secondWordIndex = i % 26;
let sumWord = `${wordsArr[firstWordIndex]}${wordsArr[secondWordIndex]}`;
headerArr.push(sumWord);
}
}
return headerArr;
};
// 获取数组中第一个不为空的值
export const getFirstNotNullValue = (array, index) => {
if (!(array && array.length)) return false;
let r = -1;
let rowLength = array.length;
while (++r < rowLength) {
let item = array[r][index];
if (item || item === 0) return item;
}
return false;
};
const isChineseReg = new RegExp('[\\u4E00-\\u9FFF]+', 'g');
export const sortArr = (arr, index) => {
if (arr.length <= 1) return;
const firstNotNullValue = getFirstNotNullValue(arr, index);
if (!firstNotNullValue && firstNotNullValue !== 0) return;
if (!isChineseReg.test(firstNotNullValue)) {
if (isNaN(Number(firstNotNullValue))) {
// 非中文非数值
arr.sort();
} else {
// 数值型
arr.sort((a, b) => {
return a[index] - b[index];
});
}
} else {
arr.sort((a, b) => {
return a[index].localeCompare(b[index], 'zh');
});
}
};
// 倒序
export const sortDesArr = (arr, index) => {
if (arr.length <= 1) return;
const firstNotNullValue = getFirstNotNullValue(arr, index);
if (!firstNotNullValue && firstNotNullValue !== 0) return;
if (!isChineseReg.test(firstNotNullValue)) {
if (isNaN(Number(firstNotNullValue))) {
// 非中文非数值
arr.sort().reverse();
} else {
// 数值型
arr.sort((a, b) => {
return b[index] - a[index];
});
}
} else {
arr.sort((a, b) => {
return b[index].localeCompare(a[index], 'zh');
});
}
};
export const on = (ele, event, callback) => {
ele.addEventListener(event, callback);
};
export const off = (ele, event, callback) => {
ele.removeEventListener(event, callback);
};
export const attr = (ele, attribution, value) => {
if (value || value === 0) {
ele.setAttribute(attribution, value);
} else {
return ele.getAttribute(attribution);
}
}

View File

@@ -1,294 +0,0 @@
<style lang="less">
@import './styles/vue-bigdata-table.less';
</style>
<template>
<div class="v-bt-outer" ref="outer" @DOMMouseScroll="handleScroll" @scroll="handleScroll">
<div :class="wrapperClasses" :style="tableWidthStyles">
<div class="v-bt-wrapper" ref="outWrapper">
<div :class="['v-bt-header-wrapper', fixed ? 'header-wrapper-fixed' : '']" :style="headerStyle">
<slot name="top" :colWidthArr="widthArr"></slot>
<table v-if="fixedCol >= 0" :class="['v-bt-fixed-header', showFixedBoxShadow ? 'box-shadow' : '']" cellspacing="0" cellpadding="0" border="0">
<colgroup>
<col v-if="i <= fixedCol" :width="width" v-for="(width, i) in widthArr" :key="'header-key-fixed-' + i" />
</colgroup>
<tr
:style="{cursor: cursorOnHeader}"
@mousemove.capture.prevent="handleMousemove"
@mousedown="handleMousedown"
@mouseup="canNotMove"
@mouseleave="canNotMove">
<th v-if="i <= fixedCol" v-for="(col, i) in columnsHandled" :data-index="i" :key="`table-title-${i}`" style="border-right: 1px solid #e9eaec;">
<span v-if="!col.render">{{ col.title }}<sort-button v-if="showSortBtn(i)" :col-index="i" @on-sort="handleSort" @on-cancel-sort="handleCancelSort" :current-sort-col-index="sortedByColIndex" :current-sort-type="sortedType"></sort-button></span>
<render-dom v-else :render="col.render" :back-value="getComputedTableDataIndex(i)"></render-dom>
</th>
</tr>
</table>
<table ref="headerTable" style="position: absolute;left: 0;top: 0;" cellspacing="0" cellpadding="0" border="0" width="100%">
<colgroup>
<col :width="width" v-for="(width, i) in widthArr" :key="'header-key-' + i" />
</colgroup>
<tr
:style="{cursor: cursorOnHeader}"
@mousemove.capture.prevent="handleMousemove"
@mousedown="handleMousedown"
@mouseup="canNotMove"
@mouseleave="canNotMove">
<th v-for="(col, i) in columnsHandled" :data-index="i" :key="`table-title-${i}`">
<span v-if="!col.render && (i > fixedCol)">{{ col.title }}<sort-button v-if="showSortBtn(i)" :col-index="i" @on-sort="handleSort" @on-cancel-sort="handleCancelSort" :current-sort-col-index="sortedByColIndex" :current-sort-type="sortedType"></sort-button></span>
<render-dom v-else-if="(i > fixedCol)" :render="col.render" :back-value="getComputedTableDataIndex(i)"></render-dom>
</th>
</tr>
</table>
</div>
<div :class="['v-bt-content', canSelectText ? '' : 'noselect-text']" @mousedown="handleMousedownOnTable">
<div :style="{height: `${topPlaceholderHeight}px`}"></div>
<render-dom :render="renderTable"></render-dom>
<div :style="{height: `${bottomPlaceholderHeight}px`}"></div>
</div>
</div>
</div>
</div>
</template>
<script>
import renderDom from './components/renderDom';
import sortButton from './components/sort-button.vue';
import editRender from './components/input-render';
import mixins from './mixins';
export default {
name: 'bigdataTable',
components: {
renderDom,
sortButton
},
mixins: [ ...mixins ],
props: {
/**
* @description 是否显示序列号列
*/
showIndex: {
type: Boolean,
default: false
},
rowNum: Number,
colNum: Number,
/**
* @description 表格数据二维数组
*/
value: {
type: Array
},
/**
* @description 表格行高
*/
rowHeight: {
type: Number,
default: 48
},
/**
* @description 是否固定表头
*/
fixed: {
type: Boolean,
default: false
},
/**
* @description 设为true后表格列宽总是平分容器宽度减去indexWidth后的宽度
*/
fixedWrapperWidth: {
type: Boolean,
default: false
},
/**
* @description 是否取消鼠标悬浮高亮效果
*/
disabledHover: {
type: Boolean,
default: true
},
/**
* @description 表头数组,元素为单个表头的对象,【{ title: 'xxx', render: (h) => {} }】
*/
columns: {
type: Array
},
/**
* @description 表头高度
*/
colWidth: {
type: Number,
default: 100
},
/**
* @description 表头高度
*/
headerHeight: {
type: Number,
default: 52
},
/**
* @description 表头tr行的样式
*/
headerTrStyle: {
type: Object,
default: () => {
return {};
}
},
/**
* @description 序列号列宽,如果没有设置,则会根据数据行数自动计算适合的宽度
*/
indexWidth: Number,
/**
* @description 序列号渲染render
*/
indexRender: {
type: Function,
default: (h, index) => {
return h('span', index + 1);
}
},
/**
* @description 是否显示斑马线
*/
stripe: {
type: Boolean,
default: false
},
/**
* @description 当前鼠标在表头单元格左侧atLeftCellPosi像素处
*/
atLeftCellPosi: {
type: Number,
default: 80
},
/**
* @description 当前鼠标在表头单元格右侧atRightCellPosi像素处
*/
atRightCellPosi: {
type: Number,
default: 80
},
/**
* @description 固定的列的范围,[0, fixedCol]设为2即固定012列这三列横向不滚动
*/
fixedCol: {
type: Number,
default: -1
},
/**
* @description 根据表格容器高度计算内置单个表格1/3渲染的行数基础上额外渲染的行数行数越多表格接替渲染效果越好但越耗性能
*/
appendNum: {
type: Number,
default: 15
},
/**
* @description 当前是否可编辑
*/
canEdit: {
type: Boolean,
default: false
},
/**
* @description 触发编辑单元格的方式enum:['dblclick' => 双击单元格]
*/
startEditType: {
type: String,
default: 'dblclick'
},
/**
* @description 编辑单元格所渲染元素的render函数如果不传则使用内置元素
*/
editCellRender: {
type: Function,
default: editRender
},
/**
* @description 保存修改的单元格内容之前的钩子如果该函数返回false则阻止保存
*/
beforeSave: {
type: Function,
default: () => {
return true;
}
},
/**
* @description 是否可选择单元格
*/
selectable: {
type: Boolean,
default: false
},
/**
* @description 是否可粘贴如果设为true则selectable效果为true
*/
paste: {
type: Boolean,
default: false
},
/**
* @description 是否可排序
*/
sortable: {
type: Boolean,
default: false
},
/**
* @description 开启排序的列序号数组或序号
*/
sortIndex: [Array, Number],
/**
* @description 默认按指定列指定排序方式排序
*/
defaultSort: Object
},
data () {
return {
prefix: 'v-bt'
};
},
methods: {
// 涉及到表格容器尺寸变化或数据变化的情况调用此方法重新计算相关值
resize () {
this._tableResize();
},
// 获取表格横向滚动的距离
getScrollLeft () {
return this.$refs.outer.scrollLeft;
},
// 调用此方法跳转到某条数据
scrollToRow (index) {
this._scrollToIndexRow(index);
},
// canEdit为true时调用此方法使第row+1行第col+1列变为编辑状态这里的行列指的是表格显示的行和除序列号列的列
editCell (row, col) {
this._editCell(row, col);
}
},
watch: {
value (val) {
this.$nextTick(() => {
this.insideTableData = this.setIndex(this.value);
this.initSort();
this._initM();
});
},
insideTableData () {
this.resize();
},
defaultSort () {
this.insideTableData = this.setIndex(this.value);
this._initM();
this.resize();
}
},
mounted () {
this.$nextTick(() => {
this.insideTableData = this.setIndex(this.value);
this._initM();
this.resize();
});
}
};
</script>