@scenetechnology/cj_iview_table 0.0.67 → 0.0.69

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -62,6 +62,9 @@ cj_iview_table 是一个功能强大的表格组件,支持筛选、排序、
62
62
  | maxHeight | String | - | 最大高度 |
63
63
  | toolBar | Array/Boolean | true | 工具栏配置 |
64
64
  | defaultSize | Number | - | 默认分页大小 |
65
+ | rowKey | String/Boolean | id | 开启跨分页保留选中时使用的唯一键,支持如 `id`、`user.id` |
66
+ | selectedRowKeys | Array | [] | 外部传入的已选 rowKey 列表,可用于页面返回后恢复勾选 |
67
+ | reserveSelection | Boolean | false | 是否保留跨分页、跨筛选/搜索的多选结果 |
65
68
  | filterGridSpan | Number | 6 | 筛选栏栅格跨度 |
66
69
  | filterLabelWidth | Number | 80 | 筛选标签宽度 |
67
70
  | fields | Array | [] | 导出数据时需要包含的属性名 |
@@ -84,6 +87,9 @@ cj_iview_table 是一个功能强大的表格组件,支持筛选、排序、
84
87
  | 事件名 | 说明 | 回调参数 |
85
88
  |--------|------|----------|
86
89
  | on-change | 分页、排序等变化时触发 | (pagination, filters, sorter) |
90
+ | on-selection-change | 当前页选中项变化时触发 | (selection) |
91
+ | on-reserve-selection-change | 开启 `reserveSelection` 后,所有已保留选中项变化时触发 | (selection) |
92
+ | on-reserve-selection-keys-change | 开启 `reserveSelection` 后,所有已保留选中的 rowKey 列表变化时触发 | (selectedRowKeys) |
87
93
 
88
94
  ## 插槽
89
95
  | 插槽名 | 说明 |
@@ -110,6 +116,59 @@ cj_iview_table 是一个功能强大的表格组件,支持筛选、排序、
110
116
  - 通过data属性直接传入数据
111
117
  - 通过request函数异步加载数据
112
118
 
119
+ ### 4. 跨分页保留选中
120
+ 当表格包含 `type: 'selection'` 列时,可通过 `reserveSelection` 开启跨分页、跨搜索/筛选保留勾选。
121
+
122
+ ```vue
123
+ <cj_iview_table
124
+ :columns="columns"
125
+ :request="loadData"
126
+ row-key="id"
127
+ :reserveSelection="true"
128
+ @on-reserve-selection-change="handleSelectionChange"
129
+ />
130
+ ```
131
+
132
+ 说明:
133
+ - `rowKey` 必须能唯一标识一行数据,支持多级路径,例如 `user.id`
134
+ - `on-selection-change` 返回的是当前页选中项
135
+ - `on-reserve-selection-change` 返回的是所有分页/筛选范围内累计保留的选中项
136
+
137
+ ### 5. 跨页面返回后恢复勾选
138
+ 如果你会在离开列表页后再回来,需要由父页面自己保存已选 rowKey 列表,并在重新进入时通过 `selectedRowKeys` 传回组件。
139
+
140
+ ```vue
141
+ <cj_iview_table
142
+ :columns="columns"
143
+ :request="loadData"
144
+ row-key="id"
145
+ :reserveSelection="true"
146
+ :selectedRowKeys="savedSelectedRowKeys"
147
+ @on-reserve-selection-keys-change="handleReserveSelectionKeysChange"
148
+ />
149
+ ```
150
+
151
+ ```js
152
+ export default {
153
+ data () {
154
+ return {
155
+ savedSelectedRowKeys: JSON.parse(sessionStorage.getItem('table-selected-row-keys') || '[]')
156
+ }
157
+ },
158
+ methods: {
159
+ handleReserveSelectionKeysChange (selectedRowKeys) {
160
+ this.savedSelectedRowKeys = selectedRowKeys
161
+ sessionStorage.setItem('table-selected-row-keys', JSON.stringify(selectedRowKeys))
162
+ }
163
+ }
164
+ }
165
+ ```
166
+
167
+ 说明:
168
+ - `selectedRowKeys` 传的是 rowKey 数组,不是整行数据
169
+ - 组件会在数据重新加载后自动按这些 key 回显勾选
170
+ - 如果某些 key 在当前数据集中不存在,会被自动忽略
171
+
113
172
  ## 使用示例
114
173
 
115
174
  ```vue
@@ -21021,6 +21021,46 @@ module.exports = function (name) {
21021
21021
  };
21022
21022
 
21023
21023
 
21024
+ /***/ }),
21025
+
21026
+ /***/ 8237:
21027
+ /***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) {
21028
+
21029
+ "use strict";
21030
+
21031
+ var $ = __webpack_require__(6518);
21032
+ var iterate = __webpack_require__(2652);
21033
+ var aCallable = __webpack_require__(9306);
21034
+ var anObject = __webpack_require__(8551);
21035
+ var getIteratorDirect = __webpack_require__(1767);
21036
+
21037
+ var $TypeError = TypeError;
21038
+
21039
+ // `Iterator.prototype.reduce` method
21040
+ // https://tc39.es/ecma262/#sec-iterator.prototype.reduce
21041
+ $({ target: 'Iterator', proto: true, real: true }, {
21042
+ reduce: function reduce(reducer /* , initialValue */) {
21043
+ anObject(this);
21044
+ aCallable(reducer);
21045
+ var record = getIteratorDirect(this);
21046
+ var noInitial = arguments.length < 2;
21047
+ var accumulator = noInitial ? undefined : arguments[1];
21048
+ var counter = 0;
21049
+ iterate(record, function (value) {
21050
+ if (noInitial) {
21051
+ noInitial = false;
21052
+ accumulator = value;
21053
+ } else {
21054
+ accumulator = reducer(accumulator, value, counter);
21055
+ }
21056
+ counter++;
21057
+ }, { IS_RECORD: true });
21058
+ if (noInitial) throw new $TypeError('Reduce of empty iterator with no initial value');
21059
+ return accumulator;
21060
+ }
21061
+ });
21062
+
21063
+
21024
21064
  /***/ }),
21025
21065
 
21026
21066
  /***/ 8469:
@@ -25759,7 +25799,7 @@ if (typeof window !== 'undefined') {
25759
25799
  // Indicate to webpack that this file can be concatenated
25760
25800
  /* harmony default export */ var setPublicPath = (null);
25761
25801
 
25762
- ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[1]!./node_modules/babel-loader/lib/index.js!./node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./packages/components/index.vue?vue&type=template&id=694727b8&scoped=true
25802
+ ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[1]!./node_modules/babel-loader/lib/index.js!./node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./packages/components/index.vue?vue&type=template&id=6e06842e&scoped=true
25763
25803
  var render = function render() {
25764
25804
  var _vm = this,
25765
25805
  _c = _vm._self._c;
@@ -26151,6 +26191,7 @@ var render = function render() {
26151
26191
  ref: "selection",
26152
26192
  attrs: {
26153
26193
  "border": _vm.border,
26194
+ "row-key": _vm.tableRowKey,
26154
26195
  "columns": _vm.tableColumns,
26155
26196
  "loading": _vm.tableLoading,
26156
26197
  "data": _vm.dataSource,
@@ -26242,6 +26283,8 @@ var es_iterator_find = __webpack_require__(116);
26242
26283
  var es_iterator_for_each = __webpack_require__(7588);
26243
26284
  // EXTERNAL MODULE: ./node_modules/core-js/modules/es.iterator.map.js
26244
26285
  var es_iterator_map = __webpack_require__(1701);
26286
+ // EXTERNAL MODULE: ./node_modules/core-js/modules/es.iterator.reduce.js
26287
+ var es_iterator_reduce = __webpack_require__(8237);
26245
26288
  // EXTERNAL MODULE: ./node_modules/core-js/modules/es.iterator.some.js
26246
26289
  var es_iterator_some = __webpack_require__(3579);
26247
26290
  // EXTERNAL MODULE: ./node_modules/core-js/modules/es.set.difference.v2.js
@@ -36362,6 +36405,8 @@ var vue_treeselect_cjs_default = /*#__PURE__*/__webpack_require__.n(vue_treesele
36362
36405
 
36363
36406
 
36364
36407
 
36408
+
36409
+
36365
36410
 
36366
36411
 
36367
36412
 
@@ -36461,6 +36506,18 @@ var vue_treeselect_cjs_default = /*#__PURE__*/__webpack_require__.n(vue_treesele
36461
36506
  type: Object,
36462
36507
  required: false
36463
36508
  },
36509
+ rowKey: {
36510
+ type: [String, Boolean],
36511
+ default: 'id'
36512
+ },
36513
+ selectedRowKeys: {
36514
+ type: Array,
36515
+ default: () => []
36516
+ },
36517
+ reserveSelection: {
36518
+ type: Boolean,
36519
+ default: false
36520
+ },
36464
36521
  // 请求-获取数据
36465
36522
  request: {
36466
36523
  type: Function,
@@ -36497,6 +36554,9 @@ var vue_treeselect_cjs_default = /*#__PURE__*/__webpack_require__.n(vue_treesele
36497
36554
  filterCount: 0,
36498
36555
  // 选中的数据
36499
36556
  selectionItems: [],
36557
+ reserveSelectionMap: {},
36558
+ reserveSelectionKeys: [],
36559
+ isRestoringSelection: false,
36500
36560
  defToolBar: [{
36501
36561
  text: '新增',
36502
36562
  type: 'primary'
@@ -36887,6 +36947,12 @@ var vue_treeselect_cjs_default = /*#__PURE__*/__webpack_require__.n(vue_treesele
36887
36947
  */
36888
36948
  formKey() {
36889
36949
  return item => item.as ? item.as : item.key;
36950
+ },
36951
+ tableRowKey() {
36952
+ if (!this.reserveSelection) {
36953
+ return false;
36954
+ }
36955
+ return this.rowKey || false;
36890
36956
  }
36891
36957
  },
36892
36958
  watch: {
@@ -36925,11 +36991,166 @@ var vue_treeselect_cjs_default = /*#__PURE__*/__webpack_require__.n(vue_treesele
36925
36991
  this.page.total = newVal;
36926
36992
  }
36927
36993
  },
36994
+ dataSource() {
36995
+ if (this.shouldReserveSelection()) {
36996
+ this.queueRestoreSelection();
36997
+ }
36998
+ },
36999
+ selectedRowKeys: {
37000
+ immediate: true,
37001
+ deep: true,
37002
+ handler(newVal) {
37003
+ if (this.shouldReserveSelection()) {
37004
+ this.applySelectedRowKeys(newVal);
37005
+ }
37006
+ }
37007
+ },
36928
37008
  requestParams() {
36929
37009
  this.reload();
36930
37010
  }
36931
37011
  },
36932
37012
  methods: {
37013
+ normalizeRowKeyValue(value) {
37014
+ return this.hasValidRowKey(value) ? String(value) : '';
37015
+ },
37016
+ hasValidRowKey(value) {
37017
+ return value !== undefined && value !== null && value !== '';
37018
+ },
37019
+ getRowIdentity(row) {
37020
+ if (!row || !this.rowKey || typeof this.rowKey !== 'string') {
37021
+ return undefined;
37022
+ }
37023
+ return this.rowKey.split('.').reduce((result, key) => {
37024
+ return result == null ? undefined : result[key];
37025
+ }, row);
37026
+ },
37027
+ shouldReserveSelection() {
37028
+ return this.reserveSelection && this.columns.some(item => item.type === 'selection') && typeof this.rowKey === 'string' && this.rowKey !== '';
37029
+ },
37030
+ normalizeSelectedRowKeys(selectedRowKeys = []) {
37031
+ if (!Array.isArray(selectedRowKeys)) {
37032
+ return [];
37033
+ }
37034
+ return Array.from(new Set(selectedRowKeys.map(item => this.normalizeRowKeyValue(item)).filter(Boolean)));
37035
+ },
37036
+ setReserveSelectionState(nextMap = {}, nextKeys = []) {
37037
+ const normalizedKeys = this.normalizeSelectedRowKeys(nextKeys);
37038
+ const normalizedMap = normalizedKeys.reduce((result, key) => {
37039
+ if (nextMap[key]) {
37040
+ result[key] = nextMap[key];
37041
+ }
37042
+ return result;
37043
+ }, {});
37044
+ this.reserveSelectionMap = normalizedMap;
37045
+ this.reserveSelectionKeys = normalizedKeys;
37046
+ this.selectionItems = normalizedKeys.map(key => normalizedMap[key]).filter(Boolean);
37047
+ },
37048
+ applySelectedRowKeys(selectedRowKeys = []) {
37049
+ if (!this.shouldReserveSelection()) {
37050
+ return;
37051
+ }
37052
+ const normalizedKeys = this.normalizeSelectedRowKeys(selectedRowKeys);
37053
+ const selectedKeySet = new Set(normalizedKeys);
37054
+ const nextMap = normalizedKeys.reduce((result, key) => {
37055
+ if (this.reserveSelectionMap[key]) {
37056
+ result[key] = this.reserveSelectionMap[key];
37057
+ }
37058
+ return result;
37059
+ }, {});
37060
+ this.dataSource.forEach(row => {
37061
+ const rowKey = this.normalizeRowKeyValue(this.getRowIdentity(row));
37062
+ if (rowKey && selectedKeySet.has(rowKey)) {
37063
+ nextMap[rowKey] = row;
37064
+ }
37065
+ });
37066
+ this.setReserveSelectionState(nextMap, normalizedKeys);
37067
+ this.queueRestoreSelection();
37068
+ },
37069
+ getReserveSelectionKeys() {
37070
+ return [...this.reserveSelectionKeys];
37071
+ },
37072
+ syncReserveSelection(selectionItems = []) {
37073
+ if (!this.shouldReserveSelection()) {
37074
+ this.selectionItems = selectionItems;
37075
+ return;
37076
+ }
37077
+ const nextMap = {
37078
+ ...this.reserveSelectionMap
37079
+ };
37080
+ const nextKeys = new Set(this.reserveSelectionKeys);
37081
+ const pageKeys = [];
37082
+ this.dataSource.forEach(row => {
37083
+ const rowKey = this.normalizeRowKeyValue(this.getRowIdentity(row));
37084
+ if (rowKey) {
37085
+ pageKeys.push(rowKey);
37086
+ }
37087
+ });
37088
+ pageKeys.forEach(key => {
37089
+ delete nextMap[key];
37090
+ nextKeys.delete(key);
37091
+ });
37092
+ selectionItems.forEach(row => {
37093
+ const rowKey = this.normalizeRowKeyValue(this.getRowIdentity(row));
37094
+ if (rowKey) {
37095
+ nextMap[rowKey] = row;
37096
+ nextKeys.add(rowKey);
37097
+ }
37098
+ });
37099
+ this.setReserveSelectionState(nextMap, Array.from(nextKeys));
37100
+ },
37101
+ getCurrentTableSelection() {
37102
+ const tableRef = this.$refs.selection;
37103
+ if (tableRef && typeof tableRef.getSelection === 'function') {
37104
+ return tableRef.getSelection();
37105
+ }
37106
+ return [];
37107
+ },
37108
+ queueRestoreSelection() {
37109
+ this.$nextTick(() => {
37110
+ this.restoreSelection();
37111
+ });
37112
+ },
37113
+ restoreSelection() {
37114
+ if (!this.shouldReserveSelection()) {
37115
+ return;
37116
+ }
37117
+ const tableRef = this.$refs.selection;
37118
+ if (!tableRef || typeof tableRef.toggleSelect !== 'function') {
37119
+ return;
37120
+ }
37121
+ const selectedKeys = new Set(this.reserveSelectionKeys);
37122
+ const currentSelection = this.getCurrentTableSelection();
37123
+ const currentSelectionKeys = new Set(currentSelection.map(row => this.getRowIdentity(row)).map(rowKey => this.normalizeRowKeyValue(rowKey)).filter(Boolean));
37124
+ this.isRestoringSelection = true;
37125
+ this.dataSource.forEach((row, index) => {
37126
+ const rowKey = this.getRowIdentity(row);
37127
+ const normalizedKey = this.normalizeRowKeyValue(rowKey);
37128
+ if (!normalizedKey) {
37129
+ return;
37130
+ }
37131
+ const shouldBeSelected = selectedKeys.has(normalizedKey);
37132
+ const isSelected = currentSelectionKeys.has(normalizedKey);
37133
+ if (shouldBeSelected !== isSelected) {
37134
+ tableRef.toggleSelect(index, rowKey);
37135
+ }
37136
+ });
37137
+ this.$nextTick(() => {
37138
+ this.isRestoringSelection = false;
37139
+ });
37140
+ },
37141
+ clearReserveSelection() {
37142
+ this.setReserveSelectionState({}, []);
37143
+ const selectedRowKeys = new Set(this.getCurrentTableSelection().map(row => this.getRowIdentity(row)).map(rowKey => this.normalizeRowKeyValue(rowKey)).filter(Boolean));
37144
+ this.dataSource.forEach((row, index) => {
37145
+ const rowKey = this.getRowIdentity(row);
37146
+ const normalizedKey = this.normalizeRowKeyValue(rowKey);
37147
+ if (normalizedKey && selectedRowKeys.has(normalizedKey) && this.$refs.selection && typeof this.$refs.selection.toggleSelect === 'function') {
37148
+ this.$refs.selection.toggleSelect(index, rowKey);
37149
+ }
37150
+ });
37151
+ this.$emit('on-reserve-selection-change', []);
37152
+ this.$emit('on-reserve-selection-keys-change', []);
37153
+ },
36933
37154
  isJsonString(str) {
36934
37155
  if (typeof str !== 'string') return false;
36935
37156
  try {
@@ -37256,7 +37477,16 @@ var vue_treeselect_cjs_default = /*#__PURE__*/__webpack_require__.n(vue_treesele
37256
37477
  * @param {*} selectionItems
37257
37478
  */
37258
37479
  onSelectionChange(selectionItems) {
37259
- this.selectionItems = selectionItems;
37480
+ if (this.shouldReserveSelection()) {
37481
+ this.syncReserveSelection(selectionItems);
37482
+ if (this.isRestoringSelection) {
37483
+ return;
37484
+ }
37485
+ this.$emit('on-reserve-selection-change', this.selectionItems);
37486
+ this.$emit('on-reserve-selection-keys-change', this.getReserveSelectionKeys());
37487
+ } else {
37488
+ this.selectionItems = selectionItems;
37489
+ }
37260
37490
  // 向父组件发射选择变化事件
37261
37491
  this.$emit('on-selection-change', selectionItems);
37262
37492
  },
@@ -37372,7 +37602,7 @@ var vue_treeselect_cjs_default = /*#__PURE__*/__webpack_require__.n(vue_treesele
37372
37602
  * 刷新
37373
37603
  */
37374
37604
  reload() {
37375
- if (this.selectionItems.length > 0) {
37605
+ if (!this.shouldReserveSelection() && this.selectionItems.length > 0) {
37376
37606
  this.selectionItems.length = 0;
37377
37607
  }
37378
37608
  this.getDataSource();
@@ -37926,15 +38156,15 @@ var vue_treeselect_cjs_default = /*#__PURE__*/__webpack_require__.n(vue_treesele
37926
38156
  });
37927
38157
  ;// ./packages/components/index.vue?vue&type=script&lang=js
37928
38158
  /* harmony default export */ var packages_componentsvue_type_script_lang_js = (componentsvue_type_script_lang_js);
37929
- ;// ./node_modules/mini-css-extract-plugin/dist/loader.js??clonedRuleSet-32.use[0]!./node_modules/css-loader/dist/cjs.js??clonedRuleSet-32.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-32.use[2]!./node_modules/less-loader/dist/cjs.js??clonedRuleSet-32.use[3]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./packages/components/index.vue?vue&type=style&index=0&id=694727b8&prod&scoped=true&lang=less
38159
+ ;// ./node_modules/mini-css-extract-plugin/dist/loader.js??clonedRuleSet-32.use[0]!./node_modules/css-loader/dist/cjs.js??clonedRuleSet-32.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-32.use[2]!./node_modules/less-loader/dist/cjs.js??clonedRuleSet-32.use[3]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./packages/components/index.vue?vue&type=style&index=0&id=6e06842e&prod&scoped=true&lang=less
37930
38160
  // extracted by mini-css-extract-plugin
37931
38161
 
37932
- ;// ./packages/components/index.vue?vue&type=style&index=0&id=694727b8&prod&scoped=true&lang=less
38162
+ ;// ./packages/components/index.vue?vue&type=style&index=0&id=6e06842e&prod&scoped=true&lang=less
37933
38163
 
37934
- ;// ./node_modules/mini-css-extract-plugin/dist/loader.js??clonedRuleSet-12.use[0]!./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./packages/components/index.vue?vue&type=style&index=1&id=694727b8&prod&lang=css
38164
+ ;// ./node_modules/mini-css-extract-plugin/dist/loader.js??clonedRuleSet-12.use[0]!./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./packages/components/index.vue?vue&type=style&index=1&id=6e06842e&prod&lang=css
37935
38165
  // extracted by mini-css-extract-plugin
37936
38166
 
37937
- ;// ./packages/components/index.vue?vue&type=style&index=1&id=694727b8&prod&lang=css
38167
+ ;// ./packages/components/index.vue?vue&type=style&index=1&id=6e06842e&prod&lang=css
37938
38168
 
37939
38169
  ;// ./packages/components/index.vue
37940
38170
 
@@ -37952,7 +38182,7 @@ var components_component = normalizeComponent(
37952
38182
  staticRenderFns,
37953
38183
  false,
37954
38184
  null,
37955
- "694727b8",
38185
+ "6e06842e",
37956
38186
  null
37957
38187
 
37958
38188
  )