vant 2.13.8 → 2.13.9
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/changelog.generated.md +8 -4
- package/es/index.js +1 -1
- package/es/sku/Sku.js +107 -35
- package/es/sku/utils/sku-helper.js +120 -2
- package/lib/index.js +1 -1
- package/lib/sku/Sku.js +109 -37
- package/lib/sku/utils/sku-helper.js +125 -4
- package/lib/vant.js +227 -37
- package/lib/vant.min.js +1 -1
- package/package.json +1 -1
- package/vetur/attributes.json +468 -468
- package/vetur/tags.json +181 -181
- package/vetur/web-types.json +1407 -1407
package/changelog.generated.md
CHANGED
@@ -1,7 +1,11 @@
|
|
1
|
-
### [v2.13.
|
1
|
+
### [v2.13.9](https://github.com/vant-ui/vant/compare/v2.13.8...v2.13.9)
|
2
2
|
|
3
|
-
`2025-
|
3
|
+
`2025-07-11`
|
4
4
|
|
5
|
-
**
|
5
|
+
**Feature**
|
6
6
|
|
7
|
-
- Sku:
|
7
|
+
- Sku: support disable_status field to filter disabled SKU options [#13520](https://github.com/vant-ui/vant/issues/13520)
|
8
|
+
|
9
|
+
**release**
|
10
|
+
|
11
|
+
- 2.13.9-beta.0 [90f1ae](https://github.com/vant-ui/vant/commit/90f1ae65feeea7fb1ca57a2e06180f36d48978d1)
|
package/es/index.js
CHANGED
@@ -87,7 +87,7 @@ import Tag from './tag';
|
|
87
87
|
import Toast from './toast';
|
88
88
|
import TreeSelect from './tree-select';
|
89
89
|
import Uploader from './uploader';
|
90
|
-
var version = '2.13.
|
90
|
+
var version = '2.13.9';
|
91
91
|
|
92
92
|
function install(Vue) {
|
93
93
|
var components = [ActionSheet, AddressEdit, AddressList, Area, Badge, Button, Calendar, Card, Cascader, Cell, CellGroup, Checkbox, CheckboxGroup, Circle, Col, Collapse, CollapseItem, ContactCard, ContactEdit, ContactList, CountDown, Coupon, CouponCell, CouponList, DatetimePicker, Dialog, Divider, DropdownItem, DropdownMenu, Empty, Field, Form, GoodsAction, GoodsActionButton, GoodsActionIcon, Grid, GridItem, Icon, Image, ImagePreview, IndexAnchor, IndexBar, Info, List, Loading, Locale, NavBar, NoticeBar, Notify, NumberKeyboard, Overlay, Pagination, Panel, PasswordInput, Picker, Popover, Popup, Progress, PullRefresh, Radio, RadioGroup, Rate, Row, Search, ShareSheet, Sidebar, SidebarItem, Skeleton, Sku, Slider, Step, Stepper, Steps, Sticky, SubmitBar, Swipe, SwipeCell, SwipeItem, Switch, SwitchCell, Tab, Tabbar, TabbarItem, Tabs, Tag, Toast, TreeSelect, Uploader];
|
package/es/sku/Sku.js
CHANGED
@@ -12,7 +12,7 @@ import SkuStepper from './components/SkuStepper';
|
|
12
12
|
import SkuMessages from './components/SkuMessages';
|
13
13
|
import SkuActions from './components/SkuActions';
|
14
14
|
import { createNamespace, isEmpty } from '../utils';
|
15
|
-
import { isAllSelected, isSkuChoosable, getSkuComb, getSelectedSkuValues, getSelectedPropValues, getSelectedProperties } from './utils/sku-helper';
|
15
|
+
import { isAllSelected, isSkuChoosable, getSkuComb, getSelectedSkuValues, getSelectedPropValues, getSelectedProperties, filterDisabledSkuTree } from './utils/sku-helper';
|
16
16
|
import { LIMIT_TYPE, UNSELECTED_SKU_VALUE_ID } from './constants';
|
17
17
|
var namespace = createNamespace('sku');
|
18
18
|
var createComponent = namespace[0],
|
@@ -146,7 +146,6 @@ export default createComponent({
|
|
146
146
|
value: function value(val) {
|
147
147
|
this.show = val;
|
148
148
|
},
|
149
|
-
skuTree: 'resetSelectedSku',
|
150
149
|
initialSku: function initialSku() {
|
151
150
|
this.resetStepper();
|
152
151
|
this.resetSelectedSku();
|
@@ -244,7 +243,13 @@ export default createComponent({
|
|
244
243
|
return this.sku.origin_price;
|
245
244
|
},
|
246
245
|
skuTree: function skuTree() {
|
247
|
-
|
246
|
+
var originTree = this.sku.tree || []; // 避免不必要的重复计算
|
247
|
+
|
248
|
+
if (!originTree.length || !this.skuList.length) {
|
249
|
+
return originTree;
|
250
|
+
}
|
251
|
+
|
252
|
+
return filterDisabledSkuTree(originTree, this.skuList, this.selectedSku);
|
248
253
|
},
|
249
254
|
skuList: function skuList() {
|
250
255
|
return this.sku.list || [];
|
@@ -366,7 +371,16 @@ export default createComponent({
|
|
366
371
|
resetSelectedSku: function resetSelectedSku() {
|
367
372
|
var _this3 = this;
|
368
373
|
|
369
|
-
this.selectedSku = {}; //
|
374
|
+
this.selectedSku = {}; // 检查initialSku中指定的值是否全部被禁用
|
375
|
+
|
376
|
+
var initialSkuDisabled = this.checkInitialSkuDisabled(); // 如果initialSku中的值全部被禁用,直接返回空选择
|
377
|
+
|
378
|
+
if (initialSkuDisabled) {
|
379
|
+
// 重置商品属性
|
380
|
+
this.resetSelectedProp();
|
381
|
+
return;
|
382
|
+
} // 重置 selectedSku
|
383
|
+
|
370
384
|
|
371
385
|
this.skuTree.forEach(function (item) {
|
372
386
|
_this3.selectedSku[item.k_s] = UNSELECTED_SKU_VALUE_ID;
|
@@ -380,7 +394,18 @@ export default createComponent({
|
|
380
394
|
key: key,
|
381
395
|
valueId: valueId
|
382
396
|
})) {
|
383
|
-
|
397
|
+
// 检查是否有对应的非禁用SKU
|
398
|
+
var skusWithThisValue = _this3.skuList.filter(function (sku) {
|
399
|
+
return String(sku[key]) === String(valueId);
|
400
|
+
});
|
401
|
+
|
402
|
+
var hasNonDisabledSku = skusWithThisValue.some(function (sku) {
|
403
|
+
return sku.disable_status !== 1;
|
404
|
+
});
|
405
|
+
|
406
|
+
if (hasNonDisabledSku) {
|
407
|
+
_this3.selectedSku[key] = valueId;
|
408
|
+
}
|
384
409
|
}
|
385
410
|
});
|
386
411
|
var skuValues = this.selectedSkuValues;
|
@@ -393,8 +418,51 @@ export default createComponent({
|
|
393
418
|
selectedSkuComb: _this3.selectedSkuComb
|
394
419
|
});
|
395
420
|
});
|
396
|
-
}
|
421
|
+
}
|
422
|
+
|
423
|
+
this.resetSelectedProp(); // 抛出重置事件
|
424
|
+
|
425
|
+
this.$emit('sku-reset', {
|
426
|
+
selectedSku: this.selectedSku,
|
427
|
+
selectedProp: this.selectedProp,
|
428
|
+
selectedSkuComb: this.selectedSkuComb
|
429
|
+
});
|
430
|
+
this.centerInitialSku();
|
431
|
+
},
|
432
|
+
// 检查initialSku中指定的值是否全部被禁用
|
433
|
+
checkInitialSkuDisabled: function checkInitialSkuDisabled() {
|
434
|
+
var _this4 = this;
|
435
|
+
|
436
|
+
// 如果没有initialSku或者没有skuList,则不进行检查
|
437
|
+
if (isEmpty(this.initialSku) || !this.skuList.length) {
|
438
|
+
return false;
|
439
|
+
} // 只关注 s1 到 s5 的规格键
|
440
|
+
|
441
|
+
|
442
|
+
var skuKeys = ['s1', 's2', 's3', 's4', 's5']; // 获取initialSku中有效的规格项
|
443
|
+
|
444
|
+
var initialSkuKeys = skuKeys.filter(function (key) {
|
445
|
+
return _this4.initialSku[key] !== undefined && _this4.initialSku[key] !== UNSELECTED_SKU_VALUE_ID && _this4.initialSku[key] !== '';
|
446
|
+
}); // 如果没有有效的规格项,则不进行检查
|
447
|
+
|
448
|
+
if (!initialSkuKeys.length) {
|
449
|
+
return false;
|
450
|
+
} // 查找符合initialSku的所有sku组合
|
451
|
+
|
452
|
+
|
453
|
+
var matchedSkus = this.skuList.filter(function (sku) {
|
454
|
+
return initialSkuKeys.every(function (key) {
|
455
|
+
return String(sku[key]) === String(_this4.initialSku[key]);
|
456
|
+
});
|
457
|
+
}); // 如果没有匹配的sku或者所有匹配的sku都被禁用,则返回true
|
397
458
|
|
459
|
+
return !matchedSkus.length || matchedSkus.every(function (sku) {
|
460
|
+
return sku.disable_status === 1;
|
461
|
+
});
|
462
|
+
},
|
463
|
+
// 重置商品属性
|
464
|
+
resetSelectedProp: function resetSelectedProp() {
|
465
|
+
var _this5 = this;
|
398
466
|
|
399
467
|
this.selectedProp = {};
|
400
468
|
var _this$initialSku$sele = this.initialSku.selectedProp,
|
@@ -402,7 +470,7 @@ export default createComponent({
|
|
402
470
|
|
403
471
|
this.propList.forEach(function (item) {
|
404
472
|
if (selectedProp[item.k_id]) {
|
405
|
-
|
473
|
+
_this5.selectedProp[item.k_id] = selectedProp[item.k_id];
|
406
474
|
}
|
407
475
|
});
|
408
476
|
|
@@ -426,7 +494,7 @@ export default createComponent({
|
|
426
494
|
});
|
427
495
|
|
428
496
|
if (firstEnableProp) {
|
429
|
-
|
497
|
+
_this5.selectedProp[k_id] = [firstEnableProp.id];
|
430
498
|
}
|
431
499
|
}
|
432
500
|
}
|
@@ -441,15 +509,7 @@ export default createComponent({
|
|
441
509
|
selectedProp: this.selectedProp,
|
442
510
|
selectedSkuComb: this.selectedSkuComb
|
443
511
|
});
|
444
|
-
}
|
445
|
-
|
446
|
-
|
447
|
-
this.$emit('sku-reset', {
|
448
|
-
selectedSku: this.selectedSku,
|
449
|
-
selectedProp: this.selectedProp,
|
450
|
-
selectedSkuComb: this.selectedSkuComb
|
451
|
-
});
|
452
|
-
this.centerInitialSku();
|
512
|
+
}
|
453
513
|
},
|
454
514
|
getSkuMessages: function getSkuMessages() {
|
455
515
|
return this.$refs.skuMessages ? this.$refs.skuMessages.getMessages() : {};
|
@@ -478,27 +538,39 @@ export default createComponent({
|
|
478
538
|
return t('selectSku');
|
479
539
|
},
|
480
540
|
onSelect: function onSelect(skuValue) {
|
481
|
-
var
|
541
|
+
var _this6 = this;
|
482
542
|
|
483
543
|
// 点击已选中的sku时则取消选中
|
484
|
-
|
544
|
+
var newSelectedSku = _extends({}, this.selectedSku);
|
545
|
+
|
546
|
+
if (newSelectedSku[skuValue.skuKeyStr] === skuValue.id) {
|
547
|
+
newSelectedSku[skuValue.skuKeyStr] = UNSELECTED_SKU_VALUE_ID;
|
548
|
+
} else {
|
549
|
+
newSelectedSku[skuValue.skuKeyStr] = skuValue.id;
|
550
|
+
} // 使用 Vue.set 来确保正确触发响应式更新
|
551
|
+
|
552
|
+
|
553
|
+
this.selectedSku = newSelectedSku; // 切换sku清空当前选择属性数据,触发prop-clear
|
485
554
|
|
486
555
|
if (this.isSkuProperties) {
|
487
556
|
this.selectedProp = {};
|
488
557
|
this.onPropClear();
|
489
|
-
}
|
558
|
+
} // 使用 $nextTick 等待 DOM 更新后再触发事件
|
490
559
|
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
560
|
+
|
561
|
+
this.$nextTick(function () {
|
562
|
+
_this6.$emit('sku-selected', {
|
563
|
+
skuValue: skuValue,
|
564
|
+
selectedSku: _this6.selectedSku,
|
565
|
+
selectedSkuComb: _this6.selectedSkuComb
|
566
|
+
});
|
495
567
|
});
|
496
568
|
},
|
497
569
|
onPropClear: function onPropClear() {
|
498
570
|
this.$emit('sku-prop-clear');
|
499
571
|
},
|
500
572
|
onPropSelect: function onPropSelect(propValue) {
|
501
|
-
var
|
573
|
+
var _extends2;
|
502
574
|
|
503
575
|
var arr = this.selectedProp[propValue.skuKeyStr] || [];
|
504
576
|
var pos = arr.indexOf(propValue.id);
|
@@ -511,7 +583,7 @@ export default createComponent({
|
|
511
583
|
arr.splice(0, 1, propValue.id);
|
512
584
|
}
|
513
585
|
|
514
|
-
this.selectedProp = _extends({}, this.selectedProp, (
|
586
|
+
this.selectedProp = _extends({}, this.selectedProp, (_extends2 = {}, _extends2[propValue.skuKeyStr] = arr, _extends2));
|
515
587
|
this.$emit('sku-prop-selected', {
|
516
588
|
propValue: propValue,
|
517
589
|
selectedProp: this.selectedProp,
|
@@ -522,7 +594,7 @@ export default createComponent({
|
|
522
594
|
this.selectedNum = num;
|
523
595
|
},
|
524
596
|
onPreviewImage: function onPreviewImage(selectedValue) {
|
525
|
-
var
|
597
|
+
var _this7 = this;
|
526
598
|
|
527
599
|
var imageList = this.imageList;
|
528
600
|
var index = 0;
|
@@ -556,7 +628,7 @@ export default createComponent({
|
|
556
628
|
images: this.imageList,
|
557
629
|
startPosition: index,
|
558
630
|
onClose: function onClose() {
|
559
|
-
|
631
|
+
_this7.$emit('close-preview', params);
|
560
632
|
}
|
561
633
|
});
|
562
634
|
},
|
@@ -630,18 +702,18 @@ export default createComponent({
|
|
630
702
|
this.centerInitialSku();
|
631
703
|
},
|
632
704
|
centerInitialSku: function centerInitialSku() {
|
633
|
-
var
|
705
|
+
var _this8 = this;
|
634
706
|
|
635
707
|
(this.$refs.skuRows || []).forEach(function (it) {
|
636
708
|
var _ref = it.skuRow || {},
|
637
709
|
k_s = _ref.k_s;
|
638
710
|
|
639
|
-
it.centerItem(
|
711
|
+
it.centerItem(_this8.initialSku[k_s]);
|
640
712
|
});
|
641
713
|
}
|
642
714
|
},
|
643
715
|
render: function render() {
|
644
|
-
var
|
716
|
+
var _this9 = this;
|
645
717
|
|
646
718
|
var h = arguments[0];
|
647
719
|
|
@@ -673,7 +745,7 @@ export default createComponent({
|
|
673
745
|
};
|
674
746
|
|
675
747
|
var slots = function slots(name) {
|
676
|
-
return
|
748
|
+
return _this9.slots(name, slotsProps);
|
677
749
|
};
|
678
750
|
|
679
751
|
var Header = slots('sku-header') || h(SkuHeader, {
|
@@ -755,7 +827,7 @@ export default createComponent({
|
|
755
827
|
},
|
756
828
|
"on": {
|
757
829
|
"change": function change(event) {
|
758
|
-
|
830
|
+
_this9.$emit('stepper-change', event);
|
759
831
|
}
|
760
832
|
}
|
761
833
|
});
|
@@ -789,9 +861,9 @@ export default createComponent({
|
|
789
861
|
"opened": this.onOpened
|
790
862
|
},
|
791
863
|
"model": {
|
792
|
-
value:
|
864
|
+
value: _this9.show,
|
793
865
|
callback: function callback($$v) {
|
794
|
-
|
866
|
+
_this9.show = $$v;
|
795
867
|
}
|
796
868
|
}
|
797
869
|
}, [Header, h("div", {
|
@@ -104,12 +104,129 @@ export var isSkuChoosable = function isSkuChoosable(skuList, selectedSku, skuToC
|
|
104
104
|
return skusToCheck.every(function (skuKey) {
|
105
105
|
return String(matchedSku[skuKey]) === String(sku[skuKey]);
|
106
106
|
});
|
107
|
+
}); // 检查是否有非禁用的SKU可选
|
108
|
+
|
109
|
+
var availableSku = filteredSku.filter(function (sku) {
|
110
|
+
return sku.disable_status !== 1;
|
107
111
|
});
|
108
|
-
var stock =
|
112
|
+
var stock = availableSku.reduce(function (total, sku) {
|
109
113
|
total += sku.stock_num;
|
110
114
|
return total;
|
111
115
|
}, 0);
|
112
116
|
return stock > 0;
|
117
|
+
}; // 根据disable_status字段过滤skuTree
|
118
|
+
|
119
|
+
export var filterDisabledSkuTree = function filterDisabledSkuTree(skuTree, skuList, selectedSku) {
|
120
|
+
if (selectedSku === void 0) {
|
121
|
+
selectedSku = {};
|
122
|
+
}
|
123
|
+
|
124
|
+
if (!(skuList == null ? void 0 : skuList.length)) {
|
125
|
+
return skuTree;
|
126
|
+
} // 创建规格树的深拷贝,避免修改原始数据
|
127
|
+
|
128
|
+
|
129
|
+
var treeClone = JSON.parse(JSON.stringify(skuTree)); // 对每个规格值,收集所有包含它的SKU
|
130
|
+
|
131
|
+
var specValueToSkus = {}; // 初始化规格值到SKU的映射
|
132
|
+
|
133
|
+
treeClone.forEach(function (treeItem) {
|
134
|
+
var key = treeItem.k_s;
|
135
|
+
treeItem.v.forEach(function (value) {
|
136
|
+
var valueId = value.id;
|
137
|
+
specValueToSkus[key + "-" + valueId] = [];
|
138
|
+
});
|
139
|
+
}); // 收集每个规格值对应的所有SKU
|
140
|
+
|
141
|
+
skuList.forEach(function (item) {
|
142
|
+
for (var i = 1; i <= 5; i++) {
|
143
|
+
var key = "s" + i;
|
144
|
+
var value = item[key];
|
145
|
+
|
146
|
+
if (value && value !== '0') {
|
147
|
+
var mapKey = key + "-" + value;
|
148
|
+
|
149
|
+
if (specValueToSkus[mapKey]) {
|
150
|
+
specValueToSkus[mapKey].push(item);
|
151
|
+
}
|
152
|
+
}
|
153
|
+
}
|
154
|
+
}); // 过滤规格树
|
155
|
+
|
156
|
+
return treeClone.filter(function (treeItem) {
|
157
|
+
var key = treeItem.k_s;
|
158
|
+
var isSelectedSpec = selectedSku[key] && selectedSku[key] !== UNSELECTED_SKU_VALUE_ID; // 过滤规格值
|
159
|
+
|
160
|
+
treeItem.v = treeItem.v.filter(function (value) {
|
161
|
+
var valueId = value.id;
|
162
|
+
var mapKey = key + "-" + valueId;
|
163
|
+
var relatedSkus = specValueToSkus[mapKey] || []; // 1. 如果所有包含该规格值的SKU都被明确禁用,则过滤掉该规格值
|
164
|
+
|
165
|
+
if (relatedSkus.length > 0) {
|
166
|
+
var allExplicitlyDisabled = relatedSkus.every(function (sku) {
|
167
|
+
return sku.disable_status === 1;
|
168
|
+
});
|
169
|
+
|
170
|
+
if (allExplicitlyDisabled) {
|
171
|
+
return false;
|
172
|
+
}
|
173
|
+
} // 2. 如果是已选中的值,保留它
|
174
|
+
|
175
|
+
|
176
|
+
if (isSelectedSpec && String(valueId) === String(selectedSku[key])) {
|
177
|
+
return true;
|
178
|
+
} // 3. 如果用户已经选择了其他规格,检查组合
|
179
|
+
|
180
|
+
|
181
|
+
var validSelectedEntries = Object.entries(selectedSku).filter(function (_ref) {
|
182
|
+
var selectedKey = _ref[0],
|
183
|
+
val = _ref[1];
|
184
|
+
return val !== UNSELECTED_SKU_VALUE_ID && selectedKey !== key;
|
185
|
+
} // 排除当前规格
|
186
|
+
);
|
187
|
+
|
188
|
+
if (validSelectedEntries.length > 0) {
|
189
|
+
// 创建当前组合
|
190
|
+
var combinedSelection = {}; // 添加已选规格
|
191
|
+
|
192
|
+
validSelectedEntries.forEach(function (_ref2) {
|
193
|
+
var selectedKey = _ref2[0],
|
194
|
+
val = _ref2[1];
|
195
|
+
combinedSelection[selectedKey] = val;
|
196
|
+
}); // 添加当前正在检查的规格值
|
197
|
+
|
198
|
+
combinedSelection[key] = String(valueId); // 查找满足当前组合的SKU
|
199
|
+
|
200
|
+
var matchingSku = skuList.filter(function (sku) {
|
201
|
+
return Object.entries(combinedSelection).every(function (_ref3) {
|
202
|
+
var selectedKey = _ref3[0],
|
203
|
+
selectedVal = _ref3[1];
|
204
|
+
return String(sku[selectedKey]) === String(selectedVal);
|
205
|
+
});
|
206
|
+
}); // 如果有匹配的SKU,检查它们是否全部被禁用
|
207
|
+
|
208
|
+
if (matchingSku.length > 0) {
|
209
|
+
var allDisabled = matchingSku.every(function (sku) {
|
210
|
+
return sku.disable_status === 1;
|
211
|
+
});
|
212
|
+
return !allDisabled;
|
213
|
+
}
|
214
|
+
} // 默认保留所有规格值
|
215
|
+
|
216
|
+
|
217
|
+
return true;
|
218
|
+
}); // 如果是已选中的规格项,但过滤后没有包含已选值,则隐藏
|
219
|
+
|
220
|
+
if (isSelectedSpec) {
|
221
|
+
var selectedValueExists = treeItem.v.some(function (value) {
|
222
|
+
return String(value.id) === String(selectedSku[key]);
|
223
|
+
});
|
224
|
+
return selectedValueExists;
|
225
|
+
} // 如果该规格项下没有规格值了,则隐藏整个规格项
|
226
|
+
|
227
|
+
|
228
|
+
return treeItem.v.length > 0;
|
229
|
+
});
|
113
230
|
};
|
114
231
|
export var getSelectedPropValues = function getSelectedPropValues(propList, selectedProp) {
|
115
232
|
var normalizeProp = normalizePropList(propList);
|
@@ -144,5 +261,6 @@ export default {
|
|
144
261
|
isAllSelected: isAllSelected,
|
145
262
|
isSkuChoosable: isSkuChoosable,
|
146
263
|
getSelectedPropValues: getSelectedPropValues,
|
147
|
-
getSelectedProperties: getSelectedProperties
|
264
|
+
getSelectedProperties: getSelectedProperties,
|
265
|
+
filterDisabledSkuTree: filterDisabledSkuTree
|
148
266
|
};
|
package/lib/index.js
CHANGED
@@ -361,7 +361,7 @@ exports.TreeSelect = _treeSelect.default;
|
|
361
361
|
var _uploader = _interopRequireDefault(require("./uploader"));
|
362
362
|
|
363
363
|
exports.Uploader = _uploader.default;
|
364
|
-
var version = '2.13.
|
364
|
+
var version = '2.13.9';
|
365
365
|
exports.version = version;
|
366
366
|
|
367
367
|
function install(Vue) {
|