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