feat(Sku): add disable-soldout-sku prop (#7759)

* feat(Sku): 售罄sku支持点击

* feat(Sku): add disable-soldout-sku prop

Co-authored-by: zhanglin_0715 <zhanglin_0715@youzan.com>
This commit is contained in:
木槿花开 2020-12-17 14:27:32 +08:00 committed by GitHub
parent 4af658e67a
commit 7a6e78fbf9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 105 additions and 90 deletions

View File

@ -39,7 +39,7 @@ export default {
langConfigs() { langConfigs() {
const { locales = {} } = config.site; const { locales = {} } = config.site;
return Object.keys(locales).map(key => ({ return Object.keys(locales).map((key) => ({
lang: key, lang: key,
label: locales[key].langLabel || '', label: locales[key].langLabel || '',
})); }));

View File

@ -90,7 +90,7 @@ export default {
}, },
anotherLang() { anotherLang() {
const items = this.langConfigs.filter(item => item.lang !== this.lang); const items = this.langConfigs.filter((item) => item.lang !== this.lang);
if (items.length) { if (items.length) {
return items[0]; return items[0];
} }

View File

@ -39,7 +39,7 @@ const IMPORT_STYLE_RE = /import\s+?(?:(?:".*?")|(?:'.*?'))[\s]*?(?:;|$|)/g;
// "import 'a.less';" => "import 'a.css';" // "import 'a.less';" => "import 'a.css';"
export function replaceCssImportExt(code: string) { export function replaceCssImportExt(code: string) {
return code.replace(IMPORT_STYLE_RE, str => return code.replace(IMPORT_STYLE_RE, (str) =>
str.replace(`.${CSS_LANG}`, '.css') str.replace(`.${CSS_LANG}`, '.css')
); );
} }

View File

@ -62,8 +62,8 @@ export function getDeps(filePath: string) {
const code = readFileSync(filePath, 'utf-8'); const code = readFileSync(filePath, 'utf-8');
const imports = matchImports(code); const imports = matchImports(code);
const paths = imports const paths = imports
.map(item => getPathByImport(item, filePath)) .map((item) => getPathByImport(item, filePath))
.filter(item => !!item) as string[]; .filter((item) => !!item) as string[];
depsMap[filePath] = paths; depsMap[filePath] = paths;
@ -76,7 +76,7 @@ export function getDeps(filePath: string) {
export function replaceScriptImportExt(code: string, from: string, to: string) { export function replaceScriptImportExt(code: string, from: string, to: string) {
const importLines = matchImports(code); const importLines = matchImports(code);
importLines.forEach(importLine => { importLines.forEach((importLine) => {
const result = importLine.replace(from, to); const result = importLine.replace(from, to);
code = code.replace(importLine, result); code = code.replace(importLine, result);
}); });

View File

@ -27,7 +27,7 @@ function readLine(input: string) {
function splitTableLine(line: string) { function splitTableLine(line: string) {
line = line.replace('\\|', 'JOIN'); line = line.replace('\\|', 'JOIN');
const items = line.split('|').map(item => item.trim().replace('JOIN', '|')); const items = line.split('|').map((item) => item.trim().replace('JOIN', '|'));
// remove pipe character on both sides // remove pipe character on both sides
items.pop(); items.pop();

View File

@ -1,78 +1,77 @@
export default { export default {
name: 'Navn', name: 'Navn',
tel: 'Telefon', tel: 'Telefon',
save: 'Lagre', save: 'Lagre',
confirm: 'Bekreft', confirm: 'Bekreft',
cancel: 'Avbryt', cancel: 'Avbryt',
delete: 'Slett', delete: 'Slett',
complete: 'Fullfør', complete: 'Fullfør',
loading: 'Laster...', loading: 'Laster...',
telEmpty: 'Vennligst fyll inn telefonnummer', telEmpty: 'Vennligst fyll inn telefonnummer',
nameEmpty: 'Vennligst fyll inn navn', nameEmpty: 'Vennligst fyll inn navn',
nameInvalid: 'Ugyldig navn', nameInvalid: 'Ugyldig navn',
confirmDelete: 'Er du sikker på at du vil slette?', confirmDelete: 'Er du sikker på at du vil slette?',
telInvalid: 'Ugyldig telefonnummer', telInvalid: 'Ugyldig telefonnummer',
vanCalendar: { vanCalendar: {
end: 'Slutt', end: 'Slutt',
start: 'Start', start: 'Start',
title: 'Kalendar', title: 'Kalendar',
startEnd: 'Start/Slutt', startEnd: 'Start/Slutt',
weekdays: ['Søn', 'Man', 'Tir', 'Ons', 'Tor', 'Fre', 'Lør'], weekdays: ['Søn', 'Man', 'Tir', 'Ons', 'Tor', 'Fre', 'Lør'],
monthTitle: (year: number, month: number) => `${year}/${month}`, monthTitle: (year: number, month: number) => `${year}/${month}`,
rangePrompt: (maxRange: number) => `Maks. ${maxRange} dager`, rangePrompt: (maxRange: number) => `Maks. ${maxRange} dager`,
}, },
vanContactCard: { vanContactCard: {
addText: 'Legg til kontakt info', addText: 'Legg til kontakt info',
}, },
vanContactList: { vanContactList: {
addText: 'Legg til ny kontakt', addText: 'Legg til ny kontakt',
}, },
vanPagination: { vanPagination: {
prev: 'Forrige', prev: 'Forrige',
next: 'Neste', next: 'Neste',
}, },
vanPullRefresh: { vanPullRefresh: {
pulling: 'Dra for oppdatering...', pulling: 'Dra for oppdatering...',
loosing: 'Mist for oppdatering...', loosing: 'Mist for oppdatering...',
}, },
vanSubmitBar: { vanSubmitBar: {
label: 'Totalt', label: 'Totalt',
}, },
vanCoupon: { vanCoupon: {
unlimited: 'Uendelig', unlimited: 'Uendelig',
discount: (discount: number) => `${discount * 10}% avslag`, discount: (discount: number) => `${discount * 10}% avslag`,
condition: (condition: number) => `Minst ${condition}`, condition: (condition: number) => `Minst ${condition}`,
}, },
vanCouponCell: { vanCouponCell: {
title: 'Kupong', title: 'Kupong',
tips: 'Ingen kuponger', tips: 'Ingen kuponger',
count: (count: number) => `Du har ${count} kuponger`, count: (count: number) => `Du har ${count} kuponger`,
}, },
vanCouponList: { vanCouponList: {
empty: 'Ingen kuponger', empty: 'Ingen kuponger',
exchange: 'Bytte', exchange: 'Bytte',
close: 'Lukk', close: 'Lukk',
enable: 'Tilgjengelig', enable: 'Tilgjengelig',
disabled: 'Utilgjengelig', disabled: 'Utilgjengelig',
placeholder: 'Kupong kode', placeholder: 'Kupong kode',
}, },
vanAddressEdit: { vanAddressEdit: {
area: 'Område', area: 'Område',
postal: 'Postkode', postal: 'Postkode',
areaEmpty: 'Vennligst fyll inn område', areaEmpty: 'Vennligst fyll inn område',
addressEmpty: 'Addresse kan ikke være tomt', addressEmpty: 'Addresse kan ikke være tomt',
postalEmpty: 'Feil postkode', postalEmpty: 'Feil postkode',
defaultAddress: 'Sett som standard adresse', defaultAddress: 'Sett som standard adresse',
telPlaceholder: 'Telefon', telPlaceholder: 'Telefon',
namePlaceholder: 'Navn', namePlaceholder: 'Navn',
areaPlaceholder: 'Område', areaPlaceholder: 'Område',
}, },
vanAddressEditDetail: { vanAddressEditDetail: {
label: 'Adresse', label: 'Adresse',
placeholder: 'Adresse', placeholder: 'Adresse',
}, },
vanAddressList: { vanAddressList: {
add: 'Legg til ny adresse', add: 'Legg til ny adresse',
}, },
}; };

View File

@ -1,16 +1,16 @@
import { mount } from '../../../test'; import { mount } from '../../../test';
import Paginaion from '..' import Paginaion from '..';
test('render prev-text & next-text slot', () => { test('render prev-text & next-text slot', () => {
const wrapper = mount(Paginaion, { const wrapper = mount(Paginaion, {
propsData: { propsData: {
totalItems: 50, totalItems: 50,
showPageSize: 5 showPageSize: 5,
}, },
scopedSlots: { scopedSlots: {
'prev-text': () => 'Custom PrevText', 'prev-text': () => 'Custom PrevText',
'next-text': () => 'Custom NextText', 'next-text': () => 'Custom NextText',
} },
}); });
expect(wrapper).toMatchSnapshot(); expect(wrapper).toMatchSnapshot();
@ -20,11 +20,11 @@ test('render page slot', () => {
const wrapper = mount(Paginaion, { const wrapper = mount(Paginaion, {
propsData: { propsData: {
totalItems: 50, totalItems: 50,
showPageSize: 5 showPageSize: 5,
}, },
scopedSlots: { scopedSlots: {
'page': ({ text }) => `${text}`, page: ({ text }) => `${text}`,
} },
}); });
expect(wrapper).toMatchSnapshot(); expect(wrapper).toMatchSnapshot();

View File

@ -134,6 +134,7 @@ export default {
| stepper-title | Quantity title | _string_ | `Quantity` | | stepper-title | Quantity title | _string_ | `Quantity` |
| custom-stepper-config | Custom stepper related config | _object_ | `{}` | | custom-stepper-config | Custom stepper related config | _object_ | `{}` |
| message-config | Message related config | _object_ | `{}` | | message-config | Message related config | _object_ | `{}` |
| disable-soldout-sku | Whether to disable soldout sku | _boolean_ | `true` |
| get-container | Return the mount node for sku | _string \| () => Element_ | - | | get-container | Return the mount node for sku | _string \| () => Element_ | - |
| safe-area-inset-bottom | Whether to enable bottom safe area adaptation | _boolean_ | `true` | | safe-area-inset-bottom | Whether to enable bottom safe area adaptation | _boolean_ | `true` |
| start-sale-num `v2.3.0` | Minimum quantity | _number_ | `1` | | start-sale-num `v2.3.0` | Minimum quantity | _number_ | `1` |

View File

@ -140,6 +140,7 @@ export default {
| get-container | 指定挂载的节点,[用法示例](#/zh-CN/popup#zhi-ding-gua-zai-wei-zhi) | _string \| () => Element_ | - | | get-container | 指定挂载的节点,[用法示例](#/zh-CN/popup#zhi-ding-gua-zai-wei-zhi) | _string \| () => Element_ | - |
| initial-sku | 默认选中的 sku具体参考高级用法 | _object_ | `{}` | | initial-sku | 默认选中的 sku具体参考高级用法 | _object_ | `{}` |
| show-soldout-sku | 是否展示售罄的 sku默认展示并置灰 | _boolean_ | `true` | | show-soldout-sku | 是否展示售罄的 sku默认展示并置灰 | _boolean_ | `true` |
| disable-soldout-sku | 是否禁用售罄的 sku | _boolean_ | `true` |
| safe-area-inset-bottom | 是否开启[底部安全区适配](#/zh-CN/advanced-usage#di-bu-an-quan-qu-gua-pei) | _boolean_ | `true` | | safe-area-inset-bottom | 是否开启[底部安全区适配](#/zh-CN/advanced-usage#di-bu-an-quan-qu-gua-pei) | _boolean_ | `true` |
| start-sale-num `v2.3.0` | 起售数量 | _number_ | `1` | | start-sale-num `v2.3.0` | 起售数量 | _number_ | `1` |
| properties `v2.4.2` | 商品属性 | _array_ | - | | properties `v2.4.2` | 商品属性 | _array_ | - |

View File

@ -73,6 +73,10 @@ export default createComponent({
type: Boolean, type: Boolean,
default: true, default: true,
}, },
disableSoldoutSku: {
type: Boolean,
default: true,
},
customStepperConfig: { customStepperConfig: {
type: Object, type: Object,
default: () => ({}), default: () => ({}),
@ -655,6 +659,7 @@ export default createComponent({
stepperTitle, stepperTitle,
selectedSkuComb, selectedSkuComb,
showHeaderImage, showHeaderImage,
disableSoldoutSku,
} = this; } = this;
const slotsProps = { const slotsProps = {
@ -720,6 +725,7 @@ export default createComponent({
skuKeyStr={skuTreeItem.k_s} skuKeyStr={skuTreeItem.k_s}
selectedSku={selectedSku} selectedSku={selectedSku}
skuEventBus={skuEventBus} skuEventBus={skuEventBus}
disableSoldoutSku={disableSoldoutSku}
largeImageMode={skuTreeItem.largeImageMode} largeImageMode={skuTreeItem.largeImageMode}
/> />
))} ))}

View File

@ -16,6 +16,7 @@ export default createComponent({
skuEventBus: Object, skuEventBus: Object,
selectedSku: Object, selectedSku: Object,
largeImageMode: Boolean, largeImageMode: Boolean,
disableSoldoutSku: Boolean,
skuList: { skuList: {
type: Array, type: Array,
default: () => [], default: () => [],
@ -32,6 +33,10 @@ export default createComponent({
}, },
choosable() { choosable() {
if (!this.disableSoldoutSku) {
return true;
}
return isSkuChoosable(this.skuList, this.selectedSku, { return isSkuChoosable(this.skuList, this.selectedSku, {
key: this.skuKeyStr, key: this.skuKeyStr,
valueId: this.skuValue.id, valueId: this.skuValue.id,

3
types/swipe.d.ts vendored
View File

@ -6,7 +6,10 @@ export type SwipeToOptions = {
export class Swipe extends VanComponent { export class Swipe extends VanComponent {
prev(): void; prev(): void;
next(): void; next(): void;
swipeTo(index: number, options?: SwipeToOptions): void; swipeTo(index: number, options?: SwipeToOptions): void;
resize(): void; resize(): void;
} }