kpmg-smart-table
Version:
1,480 lines (1,262 loc) • 86.2 kB
JavaScript
module.exports =
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/
/******/ // create a fake namespace object
/******/ // mode & 1: value is a module id, require it
/******/ // mode & 2: merge all properties of value into the ns
/******/ // mode & 4: return value when already ns object
/******/ // mode & 8|1: behave like require
/******/ __webpack_require__.t = function(value, mode) {
/******/ if(mode & 1) value = __webpack_require__(value);
/******/ if(mode & 8) return value;
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ var ns = Object.create(null);
/******/ __webpack_require__.r(ns);
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ return ns;
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = "fb15");
/******/ })
/************************************************************************/
/******/ ({
/***/ "5100":
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var _node_modules_mini_css_extract_plugin_dist_loader_js_ref_9_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_9_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_9_oneOf_1_2_node_modules_sass_loader_dist_cjs_js_ref_9_oneOf_1_3_node_modules_cache_loader_dist_cjs_js_ref_1_0_node_modules_vue_loader_lib_index_js_vue_loader_options_index_vue_vue_type_style_index_0_id_dab337fa_prod_lang_scss_scoped_true__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("cc6a");
/* harmony import */ var _node_modules_mini_css_extract_plugin_dist_loader_js_ref_9_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_9_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_9_oneOf_1_2_node_modules_sass_loader_dist_cjs_js_ref_9_oneOf_1_3_node_modules_cache_loader_dist_cjs_js_ref_1_0_node_modules_vue_loader_lib_index_js_vue_loader_options_index_vue_vue_type_style_index_0_id_dab337fa_prod_lang_scss_scoped_true__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_mini_css_extract_plugin_dist_loader_js_ref_9_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_9_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_9_oneOf_1_2_node_modules_sass_loader_dist_cjs_js_ref_9_oneOf_1_3_node_modules_cache_loader_dist_cjs_js_ref_1_0_node_modules_vue_loader_lib_index_js_vue_loader_options_index_vue_vue_type_style_index_0_id_dab337fa_prod_lang_scss_scoped_true__WEBPACK_IMPORTED_MODULE_0__);
/* unused harmony reexport * */
/***/ }),
/***/ "9d96":
/***/ (function(module, exports, __webpack_require__) {
// extracted by mini-css-extract-plugin
/***/ }),
/***/ "b282":
/***/ (function(module, exports, __webpack_require__) {
// extracted by mini-css-extract-plugin
/***/ }),
/***/ "bbde":
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var _node_modules_mini_css_extract_plugin_dist_loader_js_ref_9_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_9_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_9_oneOf_1_2_node_modules_sass_loader_dist_cjs_js_ref_9_oneOf_1_3_node_modules_cache_loader_dist_cjs_js_ref_1_0_node_modules_vue_loader_lib_index_js_vue_loader_options_Table_vue_vue_type_style_index_0_id_12f1df5b_prod_lang_scss_scoped_true__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("b282");
/* harmony import */ var _node_modules_mini_css_extract_plugin_dist_loader_js_ref_9_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_9_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_9_oneOf_1_2_node_modules_sass_loader_dist_cjs_js_ref_9_oneOf_1_3_node_modules_cache_loader_dist_cjs_js_ref_1_0_node_modules_vue_loader_lib_index_js_vue_loader_options_Table_vue_vue_type_style_index_0_id_12f1df5b_prod_lang_scss_scoped_true__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_mini_css_extract_plugin_dist_loader_js_ref_9_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_9_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_9_oneOf_1_2_node_modules_sass_loader_dist_cjs_js_ref_9_oneOf_1_3_node_modules_cache_loader_dist_cjs_js_ref_1_0_node_modules_vue_loader_lib_index_js_vue_loader_options_Table_vue_vue_type_style_index_0_id_12f1df5b_prod_lang_scss_scoped_true__WEBPACK_IMPORTED_MODULE_0__);
/* unused harmony reexport * */
/***/ }),
/***/ "c4e3":
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var _node_modules_mini_css_extract_plugin_dist_loader_js_ref_9_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_9_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_9_oneOf_1_2_node_modules_sass_loader_dist_cjs_js_ref_9_oneOf_1_3_node_modules_cache_loader_dist_cjs_js_ref_1_0_node_modules_vue_loader_lib_index_js_vue_loader_options_Query_vue_vue_type_style_index_0_id_77038a4d_prod_lang_scss_scoped_true__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("9d96");
/* harmony import */ var _node_modules_mini_css_extract_plugin_dist_loader_js_ref_9_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_9_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_9_oneOf_1_2_node_modules_sass_loader_dist_cjs_js_ref_9_oneOf_1_3_node_modules_cache_loader_dist_cjs_js_ref_1_0_node_modules_vue_loader_lib_index_js_vue_loader_options_Query_vue_vue_type_style_index_0_id_77038a4d_prod_lang_scss_scoped_true__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_mini_css_extract_plugin_dist_loader_js_ref_9_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_9_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_9_oneOf_1_2_node_modules_sass_loader_dist_cjs_js_ref_9_oneOf_1_3_node_modules_cache_loader_dist_cjs_js_ref_1_0_node_modules_vue_loader_lib_index_js_vue_loader_options_Query_vue_vue_type_style_index_0_id_77038a4d_prod_lang_scss_scoped_true__WEBPACK_IMPORTED_MODULE_0__);
/* unused harmony reexport * */
/***/ }),
/***/ "cc6a":
/***/ (function(module, exports, __webpack_require__) {
// extracted by mini-css-extract-plugin
/***/ }),
/***/ "fb15":
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
// ESM COMPAT FLAG
__webpack_require__.r(__webpack_exports__);
// EXPORTS
__webpack_require__.d(__webpack_exports__, "install", function() { return /* reexport */ install; });
__webpack_require__.d(__webpack_exports__, "SmartTable", function() { return /* reexport */ table; });
__webpack_require__.d(__webpack_exports__, "SmartPagination", function() { return /* reexport */ components_pagination; });
__webpack_require__.d(__webpack_exports__, "SmartQuery", function() { return /* reexport */ query; });
__webpack_require__.d(__webpack_exports__, "performance", function() { return /* reexport */ performance_namespaceObject; });
// NAMESPACE OBJECT: ./src/utils/performance.js
var performance_namespaceObject = {};
__webpack_require__.r(performance_namespaceObject);
__webpack_require__.d(performance_namespaceObject, "debounce", function() { return debounce; });
__webpack_require__.d(performance_namespaceObject, "throttle", function() { return throttle; });
__webpack_require__.d(performance_namespaceObject, "memoize", function() { return memoize; });
__webpack_require__.d(performance_namespaceObject, "rafThrottle", function() { return rafThrottle; });
__webpack_require__.d(performance_namespaceObject, "calcTextWidth", function() { return calcTextWidth; });
__webpack_require__.d(performance_namespaceObject, "flexColumnWidth", function() { return flexColumnWidth; });
// CONCATENATED MODULE: ./node_modules/@vue/cli-service/lib/commands/build/setPublicPath.js
// This file is imported into lib/wc client bundles.
if (typeof window !== 'undefined') {
var currentScript = window.document.currentScript
if (false) { var getCurrentScript; }
var src = currentScript && currentScript.src.match(/(.+\/)[^/]+\.js(\?.*)?$/)
if (src) {
__webpack_require__.p = src[1] // eslint-disable-line
}
}
// Indicate to webpack that this file can be concatenated
/* harmony default export */ var setPublicPath = (null);
// CONCATENATED MODULE: ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"84588542-vue-loader-template"}!./node_modules/vue-loader/lib/loaders/templateLoader.js??ref--5!./node_modules/cache-loader/dist/cjs.js??ref--1-0!./node_modules/vue-loader/lib??vue-loader-options!./src/components/table/src/Table.vue?vue&type=template&id=12f1df5b&scoped=true
var render = function render(){var _vm=this,_c=_vm._self._c;return _c('div',{staticClass:"smart-table-container",class:{ 'is-loading': _vm.loading }},[(_vm.showToolbar)?_c('div',{staticClass:"smart-table-toolbar"},[_vm._t("toolbar",function(){return [(_vm.title)?_c('div',{staticClass:"smart-table-toolbar__title"},[_vm._v(_vm._s(_vm.title))]):_vm._e(),_c('div',{staticClass:"smart-table-toolbar__actions"},[_vm._t("toolbar-actions")],2)]})],2):_vm._e(),_c('div',{ref:"tableWrapper",staticClass:"smart-table-wrapper",style:({ height: _vm.realTableHeight })},[_c('el-table',_vm._b({directives:[{name:"loading",rawName:"v-loading",value:(_vm.loading),expression:"loading"}],ref:"elTable",attrs:{"data":_vm.enableVirtualScroll ? _vm.visibleData : _vm.tableData,"height":_vm.realTableHeight},on:{"sort-change":_vm.handleSortChange,"selection-change":_vm.handleSelectionChange,"row-click":_vm.handleRowClick}},'el-table',_vm.tableProps,false),[(_vm.showSelection)?_c('el-table-column',{attrs:{"type":"selection","width":"50","fixed":"left","align":"center","selectable":_vm.selectable}}):_vm._e(),(_vm.showIndex)?_c('el-table-column',{attrs:{"type":"index","width":"60","fixed":"left","align":"center","label":_vm.indexLabel,"index":_vm.customIndex}}):_vm._e(),_vm._l((_vm.normalizedColumns),function(column,index){return [_vm._t(`column-${column.prop}`,function(){return [(!column.children || !column.children.length)?_c('el-table-column',_vm._b({key:`col-${column.prop || index}`,scopedSlots:_vm._u([(_vm.$scopedSlots[`header-${column.prop}`])?{key:"header",fn:function(scope){return [_vm._t(`header-${column.prop}`,null,null,scope)]}}:null,{key:"default",fn:function(scope){return [_vm._t(`content-${column.prop}`,function(){return [_c('cell-renderer',{attrs:{"column":column,"row":scope.row,"value":scope.row[column.prop],"index":scope.$index}})]},null,{ ...scope, column })]}}],null,true)},'el-table-column',_vm.getColumnProps(column),false)):_c('el-table-column',{key:`group-${column.prop || index}`,attrs:{"label":column.label,"align":column.align}},[_vm._l((column.children),function(child,childIndex){return [_c('el-table-column',_vm._b({scopedSlots:_vm._u([{key:"default",fn:function(scope){return [_vm._t(`content-${child.prop}`,function(){return [_c('cell-renderer',{attrs:{"column":child,"row":scope.row,"value":scope.row[child.prop],"index":scope.$index}})]},null,{ ...scope, column: child })]}}],null,true)},'el-table-column',_vm.getColumnProps(child),false))]})],2)]},{"column":column})]}),(_vm.$slots['action-column'] || _vm.$scopedSlots['action-column'])?_c('el-table-column',{attrs:{"label":_vm.actionColumnLabel,"width":_vm.actionColumnWidth,"fixed":_vm.actionColumnFixed,"align":_vm.actionColumnAlign},scopedSlots:_vm._u([{key:"default",fn:function(scope){return [_vm._t("action-column",null,null,scope)]}}],null,true)}):_vm._e(),(_vm.$slots.expand || _vm.$scopedSlots.expand)?[_c('el-table-column',{attrs:{"type":"expand"},scopedSlots:_vm._u([{key:"default",fn:function(scope){return [_vm._t("expand",null,null,scope)]}}],null,true)})]:_vm._e()],2),(_vm.showEmptyPlaceholder && !_vm.tableData.length && !_vm.loading)?_c('div',{staticClass:"smart-table-empty"},[_vm._t("empty",function(){return [_c('div',{staticClass:"smart-table-empty__content"},[_c('i',{staticClass:"el-icon-document"}),_c('p',[_vm._v(_vm._s(_vm.emptyText))])])]})],2):_vm._e(),(_vm.enableVirtualScroll && _vm.tableData.length)?_c('div',{staticClass:"smart-table-virtual-placeholder",style:({ height: `${_vm.virtualPlaceholderHeight}px` })}):_vm._e()],1),(_vm.showPagination && _vm.total > 0)?_c('div',{staticClass:"smart-table-pagination"},[_vm._t("pagination",function(){return [_c('smart-pagination',{attrs:{"current-page":_vm.currentPage,"page-size":_vm.pageSize,"total":_vm.total,"page-sizes":_vm.pageSizes,"layout":_vm.paginationLayout},on:{"update:currentPage":function($event){_vm.currentPage=$event},"update:current-page":function($event){_vm.currentPage=$event},"update:pageSize":function($event){_vm.pageSize=$event},"update:page-size":function($event){_vm.pageSize=$event},"size-change":_vm.handleSizeChange,"current-change":_vm.handleCurrentChange}})]})],2):_vm._e()])
}
var staticRenderFns = []
// CONCATENATED MODULE: ./src/components/table/src/Table.vue?vue&type=template&id=12f1df5b&scoped=true
// CONCATENATED MODULE: ./src/utils/performance.js
/**
* 防抖函数
* @param {Function} fn 需要防抖的函数
* @param {Number} delay 延迟时间(ms)
* @returns {Function} 防抖处理后的函数
*/
function debounce(fn, delay = 300) {
let timer = null;
return function(...args) {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, args);
timer = null;
}, delay);
};
}
/**
* 节流函数
* @param {Function} fn 需要节流的函数
* @param {Number} wait 等待时间(ms)
* @returns {Function} 节流处理后的函数
*/
function throttle(fn, wait = 300) {
let previous = 0;
let timer = null;
return function(...args) {
const now = Date.now();
const remaining = wait - (now - previous);
if (remaining <= 0 || remaining > wait) {
if (timer) {
clearTimeout(timer);
timer = null;
}
previous = now;
fn.apply(this, args);
} else if (!timer) {
timer = setTimeout(() => {
previous = Date.now();
timer = null;
fn.apply(this, args);
}, remaining);
}
};
}
/**
* 函数缓存
* @param {Function} fn 需要缓存的函数
* @returns {Function} 缓存处理后的函数
*/
function memoize(fn) {
const cache = new Map();
return function(...args) {
const key = JSON.stringify(args);
if (cache.has(key)) {
return cache.get(key);
}
const result = fn.apply(this, args);
cache.set(key, result);
return result;
};
}
/**
* RAF节流
* 使用requestAnimationFrame实现的节流函数
* @param {Function} fn 需要节流的函数
* @returns {Function} 节流处理后的函数
*/
function rafThrottle(fn) {
let locked = false;
return function(...args) {
if (locked) return;
locked = true;
window.requestAnimationFrame(() => {
fn.apply(this, args);
locked = false;
});
};
}
/**
* 计算字符串显示宽度(粗略)
* 用于表格自动宽度计算
* @param {String} str 要计算的字符串
* @returns {Number} 字符宽度(px)
*/
function calcTextWidth(str) {
if (!str) return 0;
// 英文字符和数字宽度为10px, 中文字符宽度为18px
let width = 0;
for (let i = 0; i < str.length; i++) {
const char = str.charCodeAt(i);
// 中文字符范围
if (char >= 0x4e00 && char <= 0x9fa5) {
width += 18;
} else {
width += 10;
}
}
return width;
}
/**
* 自动计算表格列宽
* @param {String} fieldName 字段名
* @param {Array} data 表格数据
* @param {String} title 列标题
* @param {Number} min 最小宽度
* @param {Number} max 最大宽度
* @returns {Number} 建议列宽
*/
function flexColumnWidth(fieldName, data = [], title = '', min = 80, max = 250) {
// 标题宽度
const titleWidth = calcTextWidth(title) + 30; // 30px为内边距
if (!fieldName || !data || !data.length) {
return Math.max(min, titleWidth);
}
// 内容最大宽度
let maxContentWidth = 0;
for (let i = 0; i < data.length; i++) {
const item = data[i];
const value = item[fieldName];
if (value !== undefined && value !== null) {
const valueStr = value.toString();
const currentWidth = calcTextWidth(valueStr) + 30; // 30px为内边距
maxContentWidth = Math.max(maxContentWidth, currentWidth);
}
}
// 取标题宽度和内容宽度的最大值
const suggestedWidth = Math.max(titleWidth, maxContentWidth);
// 限制在最小和最大宽度之间
return Math.min(max, Math.max(min, suggestedWidth));
}
// CONCATENATED MODULE: ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"84588542-vue-loader-template"}!./node_modules/vue-loader/lib/loaders/templateLoader.js??ref--5!./node_modules/cache-loader/dist/cjs.js??ref--1-0!./node_modules/vue-loader/lib??vue-loader-options!./src/components/pagination/index.vue?vue&type=template&id=dab337fa&scoped=true
var paginationvue_type_template_id_dab337fa_scoped_true_render = function render(){var _vm=this,_c=_vm._self._c;return _c('div',{staticClass:"smart-pagination"},[_c('el-pagination',_vm._b({attrs:{"current-page":_vm.currentPage,"page-size":_vm.pageSize,"total":_vm.total,"page-sizes":_vm.pageSizes,"layout":_vm.layout},on:{"size-change":_vm.handleSizeChange,"current-change":_vm.handleCurrentChange,"prev-click":_vm.handlePrevClick,"next-click":_vm.handleNextClick},scopedSlots:_vm._u([_vm._l((_vm.$slots),function(_,name){return {key:name,fn:function(slotData){return [_vm._t(name,null,null,slotData)]}}})],null,true)},'el-pagination',_vm.paginationProps,false)),(_vm.showQuickJumper)?_c('div',{staticClass:"smart-pagination__jumper"},[_c('span',[_vm._v("跳至")]),_c('el-input',{staticClass:"smart-pagination__jumper-input",attrs:{"size":"mini"},nativeOn:{"keyup":function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,"enter",13,$event.key,"Enter"))return null;return _vm.handleJumpTo.apply(null, arguments)}},model:{value:(_vm.jumpPage),callback:function ($$v) {_vm.jumpPage=_vm._n($$v)},expression:"jumpPage"}}),_c('span',[_vm._v("页")])],1):_vm._e(),(_vm.showSizeChanger && !_vm.layout.includes('sizes'))?_c('div',{staticClass:"smart-pagination__sizer"},[_c('el-select',{attrs:{"size":"mini"},on:{"change":_vm.handleSizeChange},model:{value:(_vm.internalPageSize),callback:function ($$v) {_vm.internalPageSize=$$v},expression:"internalPageSize"}},_vm._l((_vm.pageSizes),function(item){return _c('el-option',{key:item,attrs:{"label":`${item}条/页`,"value":item}})}),1)],1):_vm._e()],1)
}
var paginationvue_type_template_id_dab337fa_scoped_true_staticRenderFns = []
// CONCATENATED MODULE: ./src/components/pagination/index.vue?vue&type=template&id=dab337fa&scoped=true
// CONCATENATED MODULE: ./node_modules/cache-loader/dist/cjs.js??ref--1-0!./node_modules/vue-loader/lib??vue-loader-options!./src/components/pagination/index.vue?vue&type=script&lang=js
/* harmony default export */ var paginationvue_type_script_lang_js = ({
name: 'SmartPagination',
props: {
// 当前页码
currentPage: {
type: Number,
default: 1
},
// 每页显示条数
pageSize: {
type: Number,
default: 20
},
// 总条目数
total: {
type: Number,
default: 0
},
// 每页显示条数选项
pageSizes: {
type: Array,
default: () => [10, 20, 50, 100, 200]
},
// 分页布局
layout: {
type: String,
default: 'total, sizes, prev, pager, next, jumper'
},
// 是否显示快速跳转
showQuickJumper: {
type: Boolean,
default: false
},
// 是否显示每页条数选择器
showSizeChanger: {
type: Boolean,
default: true
},
// 是否显示总条数
showTotal: {
type: Boolean,
default: true
},
// 分页组件额外配置
paginationProps: {
type: Object,
default: () => ({})
},
// 小型分页
small: {
type: Boolean,
default: false
},
// 背景色
background: {
type: Boolean,
default: true
},
// 是否禁用
disabled: {
type: Boolean,
default: false
},
// 页码按钮的数量
pagerCount: {
type: Number,
default: 7
}
},
data() {
return {
internalCurrentPage: this.currentPage,
internalPageSize: this.pageSize,
jumpPage: this.currentPage
};
},
watch: {
currentPage(val) {
this.internalCurrentPage = val;
this.jumpPage = val;
},
pageSize(val) {
this.internalPageSize = val;
},
internalCurrentPage(val) {
this.$emit('update:currentPage', val);
},
internalPageSize(val) {
this.$emit('update:pageSize', val);
}
},
methods: {
// 页码变化
handleCurrentChange(page) {
this.internalCurrentPage = page;
this.jumpPage = page;
this.$emit('current-change', page);
},
// 每页条数变化
handleSizeChange(size) {
this.internalPageSize = size;
// 切换每页条数时,当前页码可能需要调整
const maxPage = Math.ceil(this.total / size) || 1;
if (this.internalCurrentPage > maxPage) {
this.handleCurrentChange(maxPage);
}
this.$emit('size-change', size);
},
// 上一页
handlePrevClick(page) {
this.$emit('prev-click', page);
},
// 下一页
handleNextClick(page) {
this.$emit('next-click', page);
},
// 跳转到指定页
handleJumpTo() {
if (!this.jumpPage || isNaN(this.jumpPage)) {
this.jumpPage = this.internalCurrentPage;
return;
}
let targetPage = this.jumpPage;
// 边界检查
if (targetPage < 1) {
targetPage = 1;
} else {
const maxPage = Math.ceil(this.total / this.internalPageSize) || 1;
if (targetPage > maxPage) {
targetPage = maxPage;
}
}
if (targetPage !== this.internalCurrentPage) {
this.handleCurrentChange(targetPage);
}
this.jumpPage = targetPage;
}
}
});
// CONCATENATED MODULE: ./src/components/pagination/index.vue?vue&type=script&lang=js
/* harmony default export */ var components_paginationvue_type_script_lang_js = (paginationvue_type_script_lang_js);
// EXTERNAL MODULE: ./src/components/pagination/index.vue?vue&type=style&index=0&id=dab337fa&prod&lang=scss&scoped=true
var paginationvue_type_style_index_0_id_dab337fa_prod_lang_scss_scoped_true = __webpack_require__("5100");
// CONCATENATED MODULE: ./node_modules/vue-loader/lib/runtime/componentNormalizer.js
/* globals __VUE_SSR_CONTEXT__ */
// IMPORTANT: Do NOT use ES2015 features in this file (except for modules).
// This module is a runtime utility for cleaner component module output and will
// be included in the final webpack user bundle.
function normalizeComponent(
scriptExports,
render,
staticRenderFns,
functionalTemplate,
injectStyles,
scopeId,
moduleIdentifier /* server only */,
shadowMode /* vue-cli only */
) {
// Vue.extend constructor export interop
var options =
typeof scriptExports === 'function' ? scriptExports.options : scriptExports
// render functions
if (render) {
options.render = render
options.staticRenderFns = staticRenderFns
options._compiled = true
}
// functional template
if (functionalTemplate) {
options.functional = true
}
// scopedId
if (scopeId) {
options._scopeId = 'data-v-' + scopeId
}
var hook
if (moduleIdentifier) {
// server build
hook = function (context) {
// 2.3 injection
context =
context || // cached call
(this.$vnode && this.$vnode.ssrContext) || // stateful
(this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext) // functional
// 2.2 with runInNewContext: true
if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') {
context = __VUE_SSR_CONTEXT__
}
// inject component styles
if (injectStyles) {
injectStyles.call(this, context)
}
// register component module identifier for async chunk inferrence
if (context && context._registeredComponents) {
context._registeredComponents.add(moduleIdentifier)
}
}
// used by ssr in case component is cached and beforeCreate
// never gets called
options._ssrRegister = hook
} else if (injectStyles) {
hook = shadowMode
? function () {
injectStyles.call(
this,
(options.functional ? this.parent : this).$root.$options.shadowRoot
)
}
: injectStyles
}
if (hook) {
if (options.functional) {
// for template-only hot-reload because in that case the render fn doesn't
// go through the normalizer
options._injectStyles = hook
// register for functional component in vue file
var originalRender = options.render
options.render = function renderWithStyleInjection(h, context) {
hook.call(context)
return originalRender(h, context)
}
} else {
// inject component registration as beforeCreate hook
var existing = options.beforeCreate
options.beforeCreate = existing ? [].concat(existing, hook) : [hook]
}
}
return {
exports: scriptExports,
options: options
}
}
// CONCATENATED MODULE: ./src/components/pagination/index.vue
/* normalize component */
var component = normalizeComponent(
components_paginationvue_type_script_lang_js,
paginationvue_type_template_id_dab337fa_scoped_true_render,
paginationvue_type_template_id_dab337fa_scoped_true_staticRenderFns,
false,
null,
"dab337fa",
null
)
/* harmony default export */ var pagination = (component.exports);
// CONCATENATED MODULE: ./src/components/pagination/index.js
pagination.install = function(Vue) {
Vue.component(pagination.name, pagination);
};
/* harmony default export */ var components_pagination = (pagination);
// CONCATENATED MODULE: ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"84588542-vue-loader-template"}!./node_modules/vue-loader/lib/loaders/templateLoader.js??ref--5!./node_modules/cache-loader/dist/cjs.js??ref--1-0!./node_modules/vue-loader/lib??vue-loader-options!./src/components/table/src/components/CellRenderer.vue?vue&type=template&id=75cca2fc
var CellRenderervue_type_template_id_75cca2fc_render = function render(){var _vm=this,_c=_vm._self._c;return _c(_vm.renderComponent,_vm._b({tag:"component",scopedSlots:_vm._u([_vm._l((_vm.$slots),function(_,name){return {key:name,fn:function(slotData){return [_vm._t(name,null,null,slotData)]}}})],null,true)},'component',_vm.componentProps,false))
}
var CellRenderervue_type_template_id_75cca2fc_staticRenderFns = []
// CONCATENATED MODULE: ./src/components/table/src/components/CellRenderer.vue?vue&type=template&id=75cca2fc
// CONCATENATED MODULE: ./node_modules/cache-loader/dist/cjs.js??ref--1-0!./node_modules/vue-loader/lib??vue-loader-options!./src/components/table/src/components/CellRenderer.vue?vue&type=script&lang=js
/* harmony default export */ var CellRenderervue_type_script_lang_js = ({
name: 'CellRenderer',
props: {
column: {
type: Object,
required: true
},
row: {
type: Object,
required: true
},
value: {
type: [String, Number, Boolean, Array, Object, Date],
default: null
},
index: {
type: Number,
default: 0
}
},
computed: {
renderComponent() {
// 根据列定义决定渲染什么组件
const { renderType } = this.column;
if (this.column.renderComponent) {
return this.column.renderComponent;
}
if (!renderType) {
return 'span';
}
// 支持多种内置渲染类型
switch (renderType) {
case 'link':
return 'el-link';
case 'tag':
return 'el-tag';
case 'image':
return 'el-image';
case 'button':
return 'el-button';
case 'switch':
return 'el-switch';
case 'progress':
return 'el-progress';
default:
return 'span';
}
},
componentProps() {
const { renderType, renderProps = {} } = this.column;
// 如果列定义了自定义渲染属性
if (this.column.renderComponentProps) {
return typeof this.column.renderComponentProps === 'function'
? this.column.renderComponentProps({ row: this.row, value: this.value, index: this.index })
: this.column.renderComponentProps;
}
// 内置渲染类型的默认属性
const defaultProps = {
// 默认就显示值内容
...{ innerHTML: this.formattedValue },
};
// 不同组件类型的特殊属性
switch (renderType) {
case 'link':
return {
type: 'primary',
underline: false,
...renderProps,
...defaultProps
};
case 'tag':
return {
type: this.getTagType(this.value),
size: 'small',
effect: 'light',
...renderProps,
...defaultProps
};
case 'image':
return {
src: this.value,
fit: 'cover',
'preview-src-list': [this.value],
style: { width: '50px', height: '50px' },
...renderProps
};
case 'button':
return {
type: 'text',
size: 'small',
...renderProps,
...defaultProps
};
case 'switch':
return {
value: Boolean(this.value),
disabled: true,
...renderProps
};
case 'progress':
return {
percentage: Number(this.value) || 0,
...renderProps
};
default:
return defaultProps;
}
},
formattedValue() {
// 如果有格式化函数,使用它
if (this.column.formatter && typeof this.column.formatter === 'function') {
return this.column.formatter(this.row, this.column, this.value, this.index);
}
// 根据数据类型格式化
const dataType = this.column.dataType || this.inferDataType();
switch (dataType) {
case 'number':
case 'NUMBER':
return this.formatNumber(this.value);
case 'date':
case 'DATE':
return this.formatDate(this.value);
case 'boolean':
case 'BOOLEAN':
return this.formatBoolean(this.value);
default:
return this.value === undefined || this.value === null ? '-' : String(this.value);
}
}
},
methods: {
// 根据值推断Tag类型
getTagType(value) {
if (this.column.tagMap && this.column.tagMap[value]) {
return this.column.tagMap[value];
}
// 默认推断规则
if (typeof value === 'string') {
if (/success|passed|完成|成功|有效|正常|active|活跃|启用|是/.test(value)) {
return 'success';
} else if (/warning|警告|注意|pending|等待|wait/.test(value)) {
return 'warning';
} else if (/danger|error|failed|失败|无效|异常|disabled|禁用|否/.test(value)) {
return 'danger';
} else if (/info|信息|primary|主要/.test(value)) {
return 'info';
}
}
return '';
},
// 推断数据类型
inferDataType() {
const { prop } = this.column;
if (!prop) return 'string';
const value = this.value;
// 根据值类型推断
if (typeof value === 'number') return 'number';
if (value instanceof Date) return 'date';
if (typeof value === 'boolean') return 'boolean';
// 根据属性名推断
if (/id$/i.test(prop) || /amount/i.test(prop) || /price/i.test(prop) || /count/i.test(prop)) {
return 'number';
}
if (/date/i.test(prop) || /time/i.test(prop) || /created/i.test(prop) || /updated/i.test(prop)) {
return 'date';
}
if (/is[A-Z]/i.test(prop) || /enable/i.test(prop) || /status/i.test(prop)) {
return 'boolean';
}
return 'string';
},
// 数字格式化
formatNumber(value, precision) {
if (value === undefined || value === null || value === '') {
return '-';
}
precision = precision || this.column.precision || 0;
if (typeof value !== 'number') {
value = parseFloat(value);
if (isNaN(value)) return '-';
}
return precision ? value.toFixed(precision) : value.toString();
},
// 日期格式化
formatDate(value) {
if (!value) return '-';
const format = this.column.dateFormat || 'YYYY-MM-DD';
const date = new Date(value);
if (isNaN(date.getTime())) return value;
// 简单实现,实际项目中可以使用日期库
return date.toLocaleDateString();
},
// 布尔值格式化
formatBoolean(value) {
if (value === undefined || value === null) return '-';
// 自定义布尔映射
if (this.column.booleanMap) {
return this.column.booleanMap[value ? 'true' : 'false'] || (value ? '是' : '否');
}
return value ? '是' : '否';
}
}
});
// CONCATENATED MODULE: ./src/components/table/src/components/CellRenderer.vue?vue&type=script&lang=js
/* harmony default export */ var components_CellRenderervue_type_script_lang_js = (CellRenderervue_type_script_lang_js);
// CONCATENATED MODULE: ./src/components/table/src/components/CellRenderer.vue
/* normalize component */
var CellRenderer_component = normalizeComponent(
components_CellRenderervue_type_script_lang_js,
CellRenderervue_type_template_id_75cca2fc_render,
CellRenderervue_type_template_id_75cca2fc_staticRenderFns,
false,
null,
null,
null
)
/* harmony default export */ var CellRenderer = (CellRenderer_component.exports);
// CONCATENATED MODULE: ./node_modules/cache-loader/dist/cjs.js??ref--1-0!./node_modules/vue-loader/lib??vue-loader-options!./src/components/table/src/Table.vue?vue&type=script&lang=js
/* harmony default export */ var Tablevue_type_script_lang_js = ({
name: 'SmartTable',
components: {
SmartPagination: components_pagination,
CellRenderer: CellRenderer
},
props: {
// 基础配置
columns: {
type: Array,
required: true,
default: () => []
},
data: {
type: Array,
default: () => []
},
height: {
type: [String, Number],
default: null
},
maxHeight: {
type: [String, Number],
default: null
},
autoHeight: {
type: Boolean,
default: false
},
title: {
type: String,
default: ''
},
showToolbar: {
type: Boolean,
default: true
},
loading: {
type: Boolean,
default: false
},
// 功能控制
showSelection: {
type: Boolean,
default: false
},
showIndex: {
type: Boolean,
default: true
},
selectable: {
type: Function,
default: null
},
showPagination: {
type: Boolean,
default: true
},
showEmptyPlaceholder: {
type: Boolean,
default: true
},
// 分页配置
total: {
type: Number,
default: 0
},
currentPage: {
type: Number,
default: 1
},
pageSize: {
type: Number,
default: 20
},
pageSizes: {
type: Array,
default: () => [10, 20, 50, 100, 200]
},
paginationLayout: {
type: String,
default: 'total, sizes, prev, pager, next, jumper'
},
// 索引列配置
indexMethod: {
type: Function,
default: null
},
indexLabel: {
type: String,
default: '序号'
},
// 操作列配置
actionColumnLabel: {
type: String,
default: '操作'
},
actionColumnWidth: {
type: [String, Number],
default: 150
},
actionColumnFixed: {
type: String,
default: 'right'
},
actionColumnAlign: {
type: String,
default: 'center'
},
// 空数据提示
emptyText: {
type: String,
default: '暂无数据'
},
// 表格扩展属性
tableProps: {
type: Object,
default: () => ({
border: true,
stripe: true,
highlightCurrentRow: true,
headerCellStyle: { background: '#F5F7FA', color: '#333' }
})
},
// 远程加载配置
remote: {
type: Boolean,
default: false
},
loadMethod: {
type: Function,
default: null
},
// 自动列宽配置
autoColumnWidth: {
type: Boolean,
default: true
},
defaultColumnWidth: {
type: [String, Number],
default: 100
},
// 行配置
rowClassName: {
type: [String, Function],
default: null
},
rowKey: {
type: [String, Function],
default: 'id'
},
// 虚拟滚动配置
enableVirtualScroll: {
type: Boolean,
default: false
},
// 每行高度(像素)
rowHeight: {
type: Number,
default: 40
},
// 预加载的行数(屏幕上下方向)
bufferSize: {
type: Number,
default: 10
},
// 大数据量阈值(超过此值启用虚拟滚动)
virtualScrollThreshold: {
type: Number,
default: 100
}
},
data() {
return {
tableData: [],
calculatedHeight: null,
selectedRows: [],
tableSort: {
prop: '',
order: ''
},
internalCurrentPage: this.currentPage,
internalPageSize: this.pageSize,
resizeObserver: null,
// 虚拟滚动相关数据
visibleData: [], // 当前可见的数据
startIndex: 0, // 当前可见数据的起始索引
endIndex: 0, // 当前可见数据的结束索引
scrollTop: 0, // 当前滚动位置
visibleCount: 0, // 可见行数
bodyWrapperEl: null, // 表格主体DOM元素
isScrolling: false, // 是否正在滚动
scrollingTimer: null, // 滚动节流定时器
_visibleDataCache: null, // 缓存可见数据
_columnPropsCache: null, // 缓存列配置
_numberFormatCache: null, // 缓存数字格式化函数
_dateFormatCache: null, // 缓存日期格式化函数
};
},
computed: {
// 优化列配置计算,使用缓存的数据类型推断
normalizedColumns() {
const cache = new Map();
return this.columns.map(column => {
const cacheKey = `${column.prop}-${column.align}-${column.width}`;
if (cache.has(cacheKey)) {
return cache.get(cacheKey);
}
const normalized = {
...column,
align: column.align || this.getDefaultAlign(column),
width: this.getColumnWidth(column),
formatter: column.formatter || this.getDefaultFormatter(column),
dataType: this.inferDataType(column)
};
cache.set(cacheKey, normalized);
return normalized;
});
},
realTableHeight() {
if (this.calculatedHeight && this.autoHeight) {
return `${this.calculatedHeight}px`;
}
if (this.height) {
return typeof this.height === 'number' ? `${this.height}px` : this.height;
}
return null;
},
// 是否应该启用虚拟滚动(数据量超过阈值且用户开启了虚拟滚动功能)
shouldUseVirtualScroll() {
return this.enableVirtualScroll && this.tableData.length > this.virtualScrollThreshold;
},
// 虚拟滚动占位高度(总行数 * 行高)
virtualPlaceholderHeight() {
return this.tableData.length * this.rowHeight;
},
// 优化可见数据计算
visibleData() {
if (!this.shouldUseVirtualScroll) {
return this.tableData;
}
const cache = this._visibleDataCache || (this._visibleDataCache = new Map());
const cacheKey = `${this.startIndex}-${this.endIndex}`;
if (cache.has(cacheKey)) {
return cache.get(cacheKey);
}
const visibleData = this.tableData.slice(this.startIndex, this.endIndex);
cache.set(cacheKey, visibleData);
// 限制缓存大小
if (cache.size > 100) {
const firstKey = cache.keys().next().value;
cache.delete(firstKey);
}
return visibleData;
}
},
watch: {
// 优化数据监听,避免深度监听带来的性能问题
data: {
handler(val) {
this.tableData = [...val];
this.$nextTick(() => {
this.updateTableLayout();
this.calculateAutoHeight();
if (this.shouldUseVirtualScroll) {
this.initVirtualScroll();
}
// 清除缓存
this._visibleDataCache = new Map();
this.getColumnWidth.cache.clear();
});
},
// 不需要深度监听
deep: false
},
// 仅当虚拟滚动相关的数据变化时才更新
startIndex() {
if (this.shouldUseVirtualScroll) {
this._visibleDataCache = new Map();
}
},
endIndex() {
if (this.shouldUseVirtualScroll) {
this._visibleDataCache = new Map();
}
},
currentPage(val) {
this.internalCurrentPage = val;
this.handlePageChange();
},
pageSize(val) {
this.internalPageSize = val;
this.handlePageChange();
},
internalCurrentPage(val) {
this.$emit('update:currentPage', val);
},
internalPageSize(val) {
this.$emit('update:pageSize', val);
}
},
created() {
// 创建带缓存的计算函数
this.memoizedGetColumnWidth = memoize(this.getColumnWidth);
this.memoizedFormatNumber = memoize(this.formatNumber);
this.memoizedFormatDate = memoize(this.formatDate);
this.memoizedInferDataType = memoize(this.inferDataType);
},
mounted() {
this.init();
this.addWindowResizeListener();
this.setupResizeObserver();
// 初始化远程加载
if (this.remote && this.loadMethod) {
this.loadRemoteData();
}
},
beforeDestroy() {
this.clearCache();
this.removeWindowResizeListener();
this.destroyResizeObserver();
this.cleanupVirtualScroll();
},
methods: {
init() {
this.calculateAutoHeight();
this.updateTableLayout();
},
// 设置ResizeObserver监听表格容器尺寸变化
setupResizeObserver() {
if (typeof ResizeObserver !== 'undefined' && this.autoHeight) {
this.resizeObserver = new ResizeObserver(throttle(() => {
this.calculateAutoHeight();
// 尺寸变化时更新虚拟滚动
if (this.shouldUseVirtualScroll) {
this.updateVisibleCount();
this.updateVisibleData();
}
}, 200));
this.resizeObserver.observe(this.$el);
}
},
destroyResizeObserver() {
if (this.resizeObserver) {
this.resizeObserver.disconnect();
this.resizeObserver = null;
}
},
addWindowResizeListener() {
if (this.autoHeight) {
window.addEventListener('resize', this.handleWindowResize);
}
},
removeWindowResizeListener() {
window.removeEventListener('resize', this.handleWindowResize);
},
handleWindowResize: throttle(function() {
this.calculateAutoHeight();
this.updateTableLayout();
// 窗口尺寸变化时更新虚拟滚动
if (this.shouldUseVirtualScroll) {
this.updateVisibleCount();
this.updateVisibleData();
}
}, 200),
// 计算表格自适应高度
calculateAutoHeight() {
if (!this.autoHeight || !this.$el) return;
this.$nextTick(() => {
const { top } = this.$el.getBoundingClientRect();
const paginationHeight = this.showPagination ? 50 : 0;
const toolbar = this.showToolbar ? this.$el.querySelector('.smart-table-toolbar') : null;
const toolbarHeight = toolbar ? toolbar.offsetHeight : 0;
// 计算表格应该占据的高度
const availableHeight = window.innerHeight - top - paginationHeight - toolbarHeight - 20; // 20px额外边距
this.calculatedHeight = Math.max(300, availableHeight);
});
},
updateTableLayout() {
this.$nextTick(() => {
if (this.$refs.elTable) {
this.$refs.elTable.doLayout();
}
});
},
// 获取列配置 - 使用缓存的列宽计算
getColumnProps(column) {
const cacheKey = `${column.prop}-${column.width}-${column.align}`;
if (this._columnPropsCache && this._columnPropsCache.has(cacheKey)) {
return this._columnPropsCache.get(cacheKey);
}
const props = {
prop: column.prop,
label: column.label,
width: this.getColumnWidth(column),
minWidth: column.minWidth,
align: column.align,
headerAlign: column.headerAlign || column.align,
fixed: column.fixed,
sortable: column.sortable,
showOverflowTooltip: column.showOverflowTooltip !== false,
formatter: column.formatter
};
if (!this._columnPropsCache) {
this._columnPropsCache = new Map();
}
this._columnPropsCache.set(cacheKey, props);
return props;
},
// 根据数据类型计算默认对齐方式
getDefaultAlign(column) {
const dataType = column.dataType || this.inferDataType(column);
switch (dataType) {
case 'number':
case 'NUMBER':
return 'right';
case 'date':
case 'DATE':
case 'boolean':
case 'BOOLEAN':
return 'center';
default:
return 'left';
}
},
// 根据属性名推断数据类型
inferDataType(column) {
const prop = column.prop;
if (!prop) return 'string';
if (/id$/i.test(prop) || /amount/i.test(prop) || /price/i.test(prop) || /count/i.test(prop)) {
return 'number';
}
if (/date/i.test(prop) || /time/i.test(prop) || /created/i.test(prop) || /updated/i.test(prop)) {
return 'date';
}
if (/is[A-Z]/i.test(prop) || /enable/i.test(prop) || /status/i.test(prop)) {
return 'boolean';
}
return 'string';
},
// 根据数据类型获取默认格式化函数
getDefaultFormatter(column) {
if (column.formatter) return column.formatter;
const dataType = column.dataType || this.inferDataType(column);
switch (dataType) {
case 'number':
case 'NUMBER':
return (row, column, cellValue) => {
if (cellValue === undefined || cellValue === null || cellValue === '') {
return '-';
}
return this.formatNumber(cellValue, column.precision);
};
case 'date':
case 'DATE':
return (row, column, cellValue) => {
if (!cellValue) return '-';
return this.formatDate(cellValue, column.dateFormat || 'YYYY-MM-DD');
};
case 'boolean':
case 'BOOLEAN':
return (row, column, cellValue) => {
if (cellValue === undefined || cellValue === null) return '-';
return cellValue ? '是' : '否';
};
default:
return (row, column, cellValue) => {
if (cellValue === undefined || cellValue === null || cellValue === '') {
return '-';
}
return cellValue;
};
}
},
// 数字格式化 - 添加缓存
formatNumber(value, precision = 2) {
const cacheKey = `${value}-${precision}`;
if (this._numberFormatCache && this._numberFormatCache.has(cacheKey)) {
return this._numberFormatCache.get(cacheKey);
}
if (!this._numberFormatCache) {
this._numberFormatCache = new Map();
}
let formattedValue;
try {
formattedValue = Number(value).toFixed(precision);
} catch (e) {
formattedValue = value;
}
this._numberFormatCache.set(cacheKey, formattedValue);
return formattedValue;
},
// 日期格式化 - 添加缓存
formatDate(value, fo