mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
refactor(Sku): rewrite SkuRow
This commit is contained in:
parent
04b78e6c49
commit
0ea2938d72
@ -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>
|
||||
))}
|
||||
|
@ -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>
|
||||
);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user