UNPKG

kpmg-smart-table

Version:
1,480 lines (1,262 loc) 86.2 kB
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