refactor(Sku): rewrite SkuRow

This commit is contained in:
chenjiahan 2020-06-26 17:03:47 +08:00 committed by neverland
parent 04b78e6c49
commit 0ea2938d72
4 changed files with 72 additions and 85 deletions

View File

@ -679,16 +679,7 @@ export default createComponent({
<div class={this.skuGroupClass}> <div class={this.skuGroupClass}>
{this.skuTree.map((skuTreeItem) => ( {this.skuTree.map((skuTreeItem) => (
<SkuRow item={skuTreeItem}> <SkuRow item={skuTreeItem}>
{skuTreeItem.v.map((skuValue, itemIndex) => ( {skuTreeItem.v.map((skuValue) => (
<template
slot={
skuTreeItem.largeImageMode
? Math.floor(itemIndex / 3) % 2 === 0
? 'sku-item-group-one'
: 'sku-item-group-two'
: 'default'
}
>
<SkuRowItem <SkuRowItem
skuList={sku.list} skuList={sku.list}
lazyLoad={lazyLoad} lazyLoad={lazyLoad}
@ -697,8 +688,7 @@ export default createComponent({
selectedSku={selectedSku} selectedSku={selectedSku}
skuEventBus={skuEventBus} skuEventBus={skuEventBus}
largeImageMode={skuTreeItem.largeImageMode} largeImageMode={skuTreeItem.largeImageMode}
></SkuRowItem> />
</template>
))} ))}
</SkuRow> </SkuRow>
))} ))}

View File

@ -5,11 +5,13 @@ import { BindEventMixin } from '../../mixins/bind-event';
const [createComponent, bem, t] = createNamespace('sku-row'); const [createComponent, bem, t] = createNamespace('sku-row');
export { bem };
export default createComponent({ export default createComponent({
mixins: [ mixins: [
BindEventMixin(function (bind) { BindEventMixin(function (bind) {
if (this.scrollable && this.$refs.content) { if (this.scrollable && this.$refs.scroller) {
bind(this.$refs.content, 'scroll', this.onScroll); bind(this.$refs.scroller, 'scroll', this.onScroll);
} }
}), }),
], ],
@ -20,10 +22,7 @@ export default createComponent({
data() { data() {
return { return {
present: 0, progress: 0,
scrollLeft: 0,
contentWidth: 0,
contentItemWidth: 0,
}; };
}, },
@ -31,64 +30,67 @@ export default createComponent({
scrollable() { scrollable() {
return this.item.largeImageMode && this.item.v.length > 6; return this.item.largeImageMode && this.item.v.length > 6;
}, },
scrollStyle() {
if (this.scrollable) {
return {
transform: `translate3d(${this.present * 20}px, 0, 0)`,
};
}
},
}, },
methods: { methods: {
onScroll() { onScroll() {
this.$nextTick(() => { const { scroller, row } = this.$refs;
const { content, contentTop } = this.$refs; const distance = row.offsetWidth - scroller.offsetWidth;
const distance = contentTop.offsetWidth - content.offsetWidth; this.progress = scroller.scrollLeft / distance;
this.present = content.scrollLeft / distance; },
});
genTitle() {
return (
<div class={bem('title')}>
{this.item.k}
{this.item.is_multiple && (
<span class={bem('title-multiple')}>{t('multiple')}</span>
)}
</div>
);
}, },
genIndicator() { genIndicator() {
if (this.scrollable) { if (this.scrollable) {
const style = {
transform: `translate3d(${this.progress * 20}px, 0, 0)`,
};
return ( return (
<div class={bem('indicator-wrapper')}> <div class={bem('indicator-wrapper')}>
<div class={bem('indicator')}> <div class={bem('indicator')}>
<div class={bem('indicator-active')} style={this.scrollStyle} /> <div class={bem('indicator-slider')} style={style} />
</div> </div>
</div> </div>
); );
} }
}, },
genContent() {
const nodes = this.slots();
if (this.item.largeImageMode) {
const middle = Math.ceil(nodes.length / 2);
return (
<div class={bem('scroller')} ref="scroller">
<div class={bem('row')} ref="row">
{nodes.slice(0, middle)}
</div>
<div class={bem('row')}>{nodes.slice(middle, nodes.length)}</div>
</div>
);
}
return nodes;
},
}, },
render() { render() {
const { item } = this;
const { largeImageMode } = item;
const multipleNode = item.is_multiple && (
<span class={bem('title-multiple')}>{t('multiple')}</span>
);
const SkuContent = (
<div class={bem('content')} ref="content">
<div class={bem('content__top')} ref="contentTop">
{this.slots('sku-item-group-one')}
</div>
<div class={bem('content__bottom')}>
{this.slots('sku-item-group-two')}
</div>
</div>
);
return ( return (
<div class={[bem(), BORDER_BOTTOM, largeImageMode && bem('picture')]}> <div class={[bem(), BORDER_BOTTOM]}>
<div class={bem('title')}> {this.genTitle()}
{item.k} {this.genContent()}
{multipleNode}
</div>
{largeImageMode ? SkuContent : this.slots()}
{this.genIndicator()} {this.genIndicator()}
</div> </div>
); );

View File

@ -1,3 +1,4 @@
import { bem } from './SkuRow';
import { createNamespace } from '../../utils'; import { createNamespace } from '../../utils';
import { isSkuChoosable } from '../utils/sku-helper'; import { isSkuChoosable } from '../utils/sku-helper';
@ -51,23 +52,22 @@ export default createComponent({
genImage(classPrefix) { genImage(classPrefix) {
const { imgUrl } = this; const { imgUrl } = this;
if (imgUrl) {
if (!imgUrl) {
return;
}
if (this.largeImageMode && this.lazyLoad) { if (this.largeImageMode && this.lazyLoad) {
return ( return <img class={`${classPrefix}-img`} src={imgUrl} vLazy={imgUrl} />;
<img class={`${classPrefix}-img`} src={imgUrl} vLazy={imgUrl} />
);
} }
return <img class={`${classPrefix}-img`} src={imgUrl} />; return <img class={`${classPrefix}-img`} src={imgUrl} />;
}
}, },
}, },
render() { render() {
const choosed = this.skuValue.id === this.selectedSku[this.skuKeyStr]; const choosed = this.skuValue.id === this.selectedSku[this.skuKeyStr];
const classPrefix = this.largeImageMode const classPrefix = this.largeImageMode ? bem('picture-item') : bem('item');
? 'van-sku-row__picture-item'
: 'van-sku-row__item';
return ( return (
<span <span

View File

@ -281,7 +281,7 @@
} }
} }
&__content { &__scroller {
overflow-x: scroll; overflow-x: scroll;
overflow-y: hidden; overflow-y: hidden;
-webkit-overflow-scrolling: touch; -webkit-overflow-scrolling: touch;
@ -289,17 +289,12 @@
&::-webkit-scrollbar { &::-webkit-scrollbar {
display: none; display: none;
} }
&__top {
display: inline-flex;
margin-bottom: 4px;
} }
&__bottom { &__row {
display: inline-flex; display: flex;
margin-bottom: 4px; margin-bottom: 4px;
} }
}
&__indicator { &__indicator {
width: 40px; width: 40px;
@ -313,7 +308,7 @@
padding-bottom: 16px; padding-bottom: 16px;
} }
&-active { &-slider {
width: 50%; width: 50%;
height: 100%; height: 100%;
background-color: @red; background-color: @red;