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

View File

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

View File

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

View File

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