mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-23 18:00:27 +08:00
feat: sku to support large image mode
This commit is contained in:
parent
489dde2114
commit
54fca31cc3
@ -140,6 +140,9 @@ export default {
|
|||||||
| start-sale-num `v2.3.0` | Minimum quantity | _number_ | `1` |
|
| start-sale-num `v2.3.0` | Minimum quantity | _number_ | `1` |
|
||||||
| properties `v2.4.2` | Goods properties | _array_ | - |
|
| properties `v2.4.2` | Goods properties | _array_ | - |
|
||||||
| preview-on-click-image `v2.5.2` | Whether to preview image when click goods image | _boolean_ | `true` |
|
| preview-on-click-image `v2.5.2` | Whether to preview image when click goods image | _boolean_ | `true` |
|
||||||
|
| supportBigPicture `v2.9.0` | Whether to display large image mode | _boolean_ | `false` |
|
||||||
|
| supportBigPictureIndex `v2.9.0` | The index value of the large image mode | _number_ | `0` |
|
||||||
|
| hasScrollTab `v2.9.0` | Whether the large image mode displays a scroll bar | _boolean_ | `false` |
|
||||||
|
|
||||||
### Events
|
### Events
|
||||||
|
|
||||||
|
@ -144,6 +144,9 @@ export default {
|
|||||||
| 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_ | - |
|
||||||
| preview-on-click-image `v2.5.2` | 是否在点击商品图片时自动预览 | _boolean_ | `true` |
|
| preview-on-click-image `v2.5.2` | 是否在点击商品图片时自动预览 | _boolean_ | `true` |
|
||||||
|
| supportBigPicture `v2.9.0` | 是否展示大图模式 | _boolean_ | `false` |
|
||||||
|
| supportBigPictureIndex `v2.9.0` | 多规格情况下,大图模式的索引值 | _number_ | `0` |
|
||||||
|
| hasScrollTab `v2.9.0` | 大图模式下,是否展示滚动条 | _boolean_ | `false` |
|
||||||
|
|
||||||
### Events
|
### Events
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import Popup from '../popup';
|
import Popup from '../popup';
|
||||||
import Toast from '../toast';
|
import Toast from '../toast';
|
||||||
|
import Lazyload from '../lazyload';
|
||||||
import ImagePreview from '../image-preview';
|
import ImagePreview from '../image-preview';
|
||||||
import SkuHeader from './components/SkuHeader';
|
import SkuHeader from './components/SkuHeader';
|
||||||
import SkuHeaderItem from './components/SkuHeaderItem';
|
import SkuHeaderItem from './components/SkuHeaderItem';
|
||||||
@ -25,6 +26,8 @@ const namespace = createNamespace('sku');
|
|||||||
const [createComponent, bem, t] = namespace;
|
const [createComponent, bem, t] = namespace;
|
||||||
const { QUOTA_LIMIT } = LIMIT_TYPE;
|
const { QUOTA_LIMIT } = LIMIT_TYPE;
|
||||||
|
|
||||||
|
Vue.use(Lazyload);
|
||||||
|
|
||||||
export default createComponent({
|
export default createComponent({
|
||||||
props: {
|
props: {
|
||||||
sku: Object,
|
sku: Object,
|
||||||
@ -98,6 +101,18 @@ export default createComponent({
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
|
supportBigPicture: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
supportBigPictureIndex: {
|
||||||
|
type: Number,
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
hasScrollTab: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
@ -616,8 +631,10 @@ export default createComponent({
|
|||||||
selectedNum,
|
selectedNum,
|
||||||
stepperTitle,
|
stepperTitle,
|
||||||
selectedSkuComb,
|
selectedSkuComb,
|
||||||
|
supportBigPicture,
|
||||||
|
supportBigPictureIndex,
|
||||||
|
hasScrollTab,
|
||||||
} = this;
|
} = this;
|
||||||
|
|
||||||
const slotsProps = {
|
const slotsProps = {
|
||||||
price,
|
price,
|
||||||
originPrice,
|
originPrice,
|
||||||
@ -634,6 +651,7 @@ export default createComponent({
|
|||||||
goods={goods}
|
goods={goods}
|
||||||
skuEventBus={skuEventBus}
|
skuEventBus={skuEventBus}
|
||||||
selectedSku={selectedSku}
|
selectedSku={selectedSku}
|
||||||
|
supportBigPicture={supportBigPicture}
|
||||||
>
|
>
|
||||||
<template slot="sku-header-image-extra">
|
<template slot="sku-header-image-extra">
|
||||||
{slots('sku-header-image-extra')}
|
{slots('sku-header-image-extra')}
|
||||||
@ -669,17 +687,44 @@ export default createComponent({
|
|||||||
slots('sku-group') ||
|
slots('sku-group') ||
|
||||||
(this.hasSkuOrAttr && (
|
(this.hasSkuOrAttr && (
|
||||||
<div class={this.skuGroupClass}>
|
<div class={this.skuGroupClass}>
|
||||||
{this.skuTree.map((skuTreeItem) => (
|
{this.skuTree.map((skuTreeItem, index) => (
|
||||||
<SkuRow skuRow={skuTreeItem}>
|
<SkuRow
|
||||||
{skuTreeItem.v.map((skuValue) => (
|
skuRow={skuTreeItem}
|
||||||
|
isShowBigPicture={
|
||||||
|
supportBigPicture && supportBigPictureIndex === index
|
||||||
|
}
|
||||||
|
hasScrollTab={hasScrollTab && skuTreeItem.v.length > 6}
|
||||||
|
>
|
||||||
|
{skuTreeItem.v.map((skuValue, itemIndex) => {
|
||||||
|
return supportBigPicture && supportBigPictureIndex === index ? (
|
||||||
|
<template
|
||||||
|
slot={
|
||||||
|
Math.floor(itemIndex / 3) % 2 === 0
|
||||||
|
? 'sku-item-group-one'
|
||||||
|
: 'sku-item-group-two'
|
||||||
|
}
|
||||||
|
>
|
||||||
<SkuRowItem
|
<SkuRowItem
|
||||||
skuList={sku.list}
|
skuList={sku.list}
|
||||||
skuValue={skuValue}
|
skuValue={skuValue}
|
||||||
selectedSku={selectedSku}
|
selectedSku={selectedSku}
|
||||||
skuEventBus={skuEventBus}
|
skuEventBus={skuEventBus}
|
||||||
skuKeyStr={skuTreeItem.k_s}
|
skuKeyStr={skuTreeItem.k_s}
|
||||||
/>
|
isShowBigPicture={
|
||||||
))}
|
supportBigPicture && supportBigPictureIndex === index
|
||||||
|
}
|
||||||
|
></SkuRowItem>
|
||||||
|
</template>
|
||||||
|
) : (
|
||||||
|
<SkuRowItem
|
||||||
|
skuList={sku.list}
|
||||||
|
skuValue={skuValue}
|
||||||
|
selectedSku={selectedSku}
|
||||||
|
skuEventBus={skuEventBus}
|
||||||
|
skuKeyStr={skuTreeItem.k_s}
|
||||||
|
></SkuRowItem>
|
||||||
|
);
|
||||||
|
})}
|
||||||
</SkuRow>
|
</SkuRow>
|
||||||
))}
|
))}
|
||||||
{this.propList.map((skuTreeItem) => (
|
{this.propList.map((skuTreeItem) => (
|
||||||
|
@ -13,6 +13,7 @@ export type SkuHeaderProps = {
|
|||||||
goods: SkuGoodsData;
|
goods: SkuGoodsData;
|
||||||
skuEventBus: Vue;
|
skuEventBus: Vue;
|
||||||
selectedSku: SelectedSkuData;
|
selectedSku: SelectedSkuData;
|
||||||
|
supportBigPicture: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type SkuHeaderSlots = DefaultSlots & {
|
export type SkuHeaderSlots = DefaultSlots & {
|
||||||
@ -49,20 +50,34 @@ function SkuHeader(
|
|||||||
slots: SkuHeaderSlots,
|
slots: SkuHeaderSlots,
|
||||||
ctx: RenderContext<SkuHeaderProps>
|
ctx: RenderContext<SkuHeaderProps>
|
||||||
) {
|
) {
|
||||||
const { sku, goods, skuEventBus, selectedSku } = props;
|
const {
|
||||||
|
sku,
|
||||||
|
goods,
|
||||||
|
skuEventBus,
|
||||||
|
selectedSku,
|
||||||
|
supportBigPicture = false,
|
||||||
|
} = props;
|
||||||
const goodsImg = getSkuImg(sku, selectedSku) || goods.picture;
|
const goodsImg = getSkuImg(sku, selectedSku) || goods.picture;
|
||||||
|
|
||||||
const previewImage = () => {
|
const previewImage = () => {
|
||||||
skuEventBus.$emit('sku:previewImage', goodsImg);
|
skuEventBus.$emit('sku:previewImage', goodsImg);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class={[bem(), BORDER_BOTTOM]} {...inherit(ctx)}>
|
<div class={[bem(), BORDER_BOTTOM]} {...inherit(ctx)}>
|
||||||
|
{!supportBigPicture && (
|
||||||
<div class={bem('img-wrap')} onClick={previewImage}>
|
<div class={bem('img-wrap')} onClick={previewImage}>
|
||||||
<img src={goodsImg} />
|
<img src={goodsImg} />
|
||||||
{slots['sku-header-image-extra']?.()}
|
{slots['sku-header-image-extra']?.()}
|
||||||
</div>
|
</div>
|
||||||
<div class={bem('goods-info')}>{slots.default?.()}</div>
|
)}
|
||||||
|
<div
|
||||||
|
class={[
|
||||||
|
bem('goods-info'),
|
||||||
|
supportBigPicture && bem('goods-info--no-padding'),
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
{slots.default?.()}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -72,6 +87,7 @@ SkuHeader.props = {
|
|||||||
goods: Object,
|
goods: Object,
|
||||||
skuEventBus: Object,
|
skuEventBus: Object,
|
||||||
selectedSku: Object,
|
selectedSku: Object,
|
||||||
|
supportBigPicture: Boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default createComponent<SkuHeaderProps>(SkuHeader);
|
export default createComponent<SkuHeaderProps>(SkuHeader);
|
||||||
|
101
src/sku/components/SkuRow.js
Normal file
101
src/sku/components/SkuRow.js
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
// Utils
|
||||||
|
import { createNamespace } from '../../utils';
|
||||||
|
import { BORDER_BOTTOM } from '../../utils/constant';
|
||||||
|
import { BindEventMixin } from '../../mixins/bind-event';
|
||||||
|
import { getScroller } from '../../utils/dom/scroll';
|
||||||
|
|
||||||
|
const [createComponent, bem, t] = createNamespace('sku-row');
|
||||||
|
|
||||||
|
export default createComponent({
|
||||||
|
mixins: [
|
||||||
|
BindEventMixin(function (bind) {
|
||||||
|
if (!(this.isShowBigPicture && this.hasScrollTab)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.scrollCon) {
|
||||||
|
this.scrollCon = getScroller(this.$refs.skuContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
bind(this.scrollCon, 'scroll', this.onScroll);
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
props: {
|
||||||
|
skuRow: Object,
|
||||||
|
isShowBigPicture: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
hasScrollTab: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
present: 0,
|
||||||
|
contentWidth: 0,
|
||||||
|
contentItemWidth: 0,
|
||||||
|
scrollLeft: 0,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
scrollStyle() {
|
||||||
|
if (!(this.isShowBigPicture && this.hasScrollTab)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this.tranX = this.present * 20;
|
||||||
|
return {
|
||||||
|
transform: `translate3d(${this.tranX}px, 0, 0)`,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onScroll() {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
const contentWidth = this.scrollCon.clientWidth;
|
||||||
|
const contentItemWidth = this.$refs.skuContentItem.clientWidth;
|
||||||
|
const distance = contentItemWidth - contentWidth;
|
||||||
|
this.present = this.scrollCon.scrollLeft / distance;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {},
|
||||||
|
render() {
|
||||||
|
const { skuRow, isShowBigPicture, hasScrollTab } = this;
|
||||||
|
const multipleNode = skuRow.is_multiple && (
|
||||||
|
<span class={bem('title-multiple')}>({t('multiple')})</span>
|
||||||
|
);
|
||||||
|
const SkuScroll = (
|
||||||
|
<div class={bem('scroll')}>
|
||||||
|
<div class={bem('scroll__content')} ref="skuScroll">
|
||||||
|
<div
|
||||||
|
class={bem('scroll__content--active')}
|
||||||
|
style={this.scrollStyle}
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
const SkuContent = (
|
||||||
|
<div class={bem('content')} ref="skuContent">
|
||||||
|
<div class={bem('content__top')} ref="skuContentItem">
|
||||||
|
{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, isShowBigPicture && bem('picture')]}>
|
||||||
|
<div class={bem('title')}>
|
||||||
|
{skuRow.k}
|
||||||
|
{multipleNode}
|
||||||
|
</div>
|
||||||
|
{isShowBigPicture ? SkuContent : this.slots()}
|
||||||
|
{isShowBigPicture && hasScrollTab && SkuScroll}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
@ -1,41 +0,0 @@
|
|||||||
// Utils
|
|
||||||
import { createNamespace } from '../../utils';
|
|
||||||
import { inherit } from '../../utils/functional';
|
|
||||||
import { BORDER_BOTTOM } from '../../utils/constant';
|
|
||||||
|
|
||||||
// Types
|
|
||||||
import { CreateElement, RenderContext } from 'vue/types';
|
|
||||||
import { DefaultSlots } from '../../utils/types';
|
|
||||||
import { SkuTreeItemData } from '../../../types/sku';
|
|
||||||
|
|
||||||
export type SkuRowProps = {
|
|
||||||
skuRow: SkuTreeItemData;
|
|
||||||
};
|
|
||||||
|
|
||||||
const [createComponent, bem, t] = createNamespace('sku-row');
|
|
||||||
|
|
||||||
function SkuRow(
|
|
||||||
h: CreateElement,
|
|
||||||
props: SkuRowProps,
|
|
||||||
slots: DefaultSlots,
|
|
||||||
ctx: RenderContext<SkuRowProps>
|
|
||||||
) {
|
|
||||||
const multipleNode = props.skuRow.is_multiple && (
|
|
||||||
<span class={bem('title-multiple')}>({t('multiple')})</span>
|
|
||||||
);
|
|
||||||
return (
|
|
||||||
<div class={[bem(), BORDER_BOTTOM]} {...inherit(ctx)}>
|
|
||||||
<div class={bem('title')}>
|
|
||||||
{props.skuRow.k}
|
|
||||||
{multipleNode}
|
|
||||||
</div>
|
|
||||||
{slots.default && slots.default()}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
SkuRow.props = {
|
|
||||||
skuRow: Object,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default createComponent<SkuRowProps>(SkuRow);
|
|
@ -13,6 +13,7 @@ export default createComponent({
|
|||||||
type: Array,
|
type: Array,
|
||||||
default: () => [],
|
default: () => [],
|
||||||
},
|
},
|
||||||
|
isShowBigPicture: Boolean,
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
@ -33,25 +34,42 @@ export default createComponent({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
onPreviewImg(event) {
|
||||||
|
event.stopPropagation();
|
||||||
|
this.skuEventBus.$emit(
|
||||||
|
'sku:previewImage',
|
||||||
|
this.skuValue.imgUrl || this.skuValue.img_url
|
||||||
|
);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const choosed = this.skuValue.id === this.selectedSku[this.skuKeyStr];
|
const choosed = this.skuValue.id === this.selectedSku[this.skuKeyStr];
|
||||||
const imgUrl = this.skuValue.imgUrl || this.skuValue.img_url;
|
const imgUrl = this.skuValue.imgUrl || this.skuValue.img_url;
|
||||||
|
const BEM_NAME = this.isShowBigPicture
|
||||||
|
? 'van-sku-row__picture-item'
|
||||||
|
: 'van-sku-row__item';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span
|
<span
|
||||||
class={[
|
class={[
|
||||||
'van-sku-row__item',
|
`${BEM_NAME}`,
|
||||||
{
|
choosed ? `${BEM_NAME}--active` : '',
|
||||||
'van-sku-row__item--active': choosed,
|
!this.choosable ? `${BEM_NAME}--disabled` : '',
|
||||||
'van-sku-row__item--disabled': !this.choosable,
|
|
||||||
},
|
|
||||||
]}
|
]}
|
||||||
onClick={this.onSelect}
|
onClick={this.onSelect}
|
||||||
>
|
>
|
||||||
{imgUrl && <img class="van-sku-row__item-img" src={imgUrl} />}
|
{this.isShowBigPicture && (
|
||||||
<span class="van-sku-row__item-name">{this.skuValue.name}</span>
|
<img
|
||||||
|
class={`${BEM_NAME}-img-icon`}
|
||||||
|
src="https://img.yzcdn.cn/upload_files/2020/06/18/Fn6Qf0fGRFyuD8xh0Gi1w2ng59G1.png"
|
||||||
|
onClick={this.onPreviewImg}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{imgUrl && (
|
||||||
|
<img class={`${BEM_NAME}-img`} src={imgUrl} v-lazy={imgUrl} />
|
||||||
|
)}
|
||||||
|
<span class={`${BEM_NAME}-name`}>{this.skuValue.name}</span>
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -29,6 +29,44 @@ export const skuData = {
|
|||||||
{
|
{
|
||||||
id: '1215',
|
id: '1215',
|
||||||
name: '白色',
|
name: '白色',
|
||||||
|
imgUrl:
|
||||||
|
'https://img.yzcdn.cn/upload_files/2017/03/16/Fs_OMbSFPa183sBwvG_94llUYiLa.jpeg?imageView2/2/w/100/h/100/q/75/format/jpg',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '1215',
|
||||||
|
name: '白色',
|
||||||
|
imgUrl:
|
||||||
|
'https://img.yzcdn.cn/upload_files/2017/03/16/Fs_OMbSFPa183sBwvG_94llUYiLa.jpeg?imageView2/2/w/100/h/100/q/75/format/jpg',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '1215',
|
||||||
|
name: '白色',
|
||||||
|
imgUrl:
|
||||||
|
'https://img.yzcdn.cn/upload_files/2017/03/16/Fs_OMbSFPa183sBwvG_94llUYiLa.jpeg?imageView2/2/w/100/h/100/q/75/format/jpg',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '1215',
|
||||||
|
name: '白色',
|
||||||
|
imgUrl:
|
||||||
|
'https://img.yzcdn.cn/upload_files/2017/03/16/Fs_OMbSFPa183sBwvG_94llUYiLa.jpeg?imageView2/2/w/100/h/100/q/75/format/jpg',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '1215',
|
||||||
|
name: '白色',
|
||||||
|
imgUrl:
|
||||||
|
'https://img.yzcdn.cn/upload_files/2017/03/16/Fs_OMbSFPa183sBwvG_94llUYiLa.jpeg?imageView2/2/w/100/h/100/q/75/format/jpg',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '1215',
|
||||||
|
name: '白色',
|
||||||
|
imgUrl:
|
||||||
|
'https://img.yzcdn.cn/upload_files/2017/03/16/Fs_OMbSFPa183sBwvG_94llUYiLa.jpeg?imageView2/2/w/100/h/100/q/75/format/jpg',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '1215',
|
||||||
|
name: '白色',
|
||||||
|
imgUrl:
|
||||||
|
'https://img.yzcdn.cn/upload_files/2017/03/16/Fs_OMbSFPa183sBwvG_94llUYiLa.jpeg?imageView2/2/w/100/h/100/q/75/format/jpg',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
k_s: 's1',
|
k_s: 's1',
|
||||||
|
@ -140,6 +140,38 @@
|
|||||||
</van-button>
|
</van-button>
|
||||||
</div>
|
</div>
|
||||||
</demo-block>
|
</demo-block>
|
||||||
|
|
||||||
|
<!-- 大图模式 -->
|
||||||
|
<demo-block :title="t('bigPicture')">
|
||||||
|
<div class="sku-container">
|
||||||
|
<van-sku
|
||||||
|
v-model="showBigPictureMode"
|
||||||
|
:sku="skuData.sku"
|
||||||
|
:goods="skuData.goods_info"
|
||||||
|
:goods-id="skuData.goods_id"
|
||||||
|
:hide-stock="skuData.sku.hide_stock"
|
||||||
|
:quota="skuData.quota"
|
||||||
|
:quota-used="skuData.quota_used"
|
||||||
|
:start-sale-num="skuData.start_sale_num"
|
||||||
|
:close-on-click-overlay="closeOnClickOverlay"
|
||||||
|
:message-config="messageConfig"
|
||||||
|
:custom-sku-validator="customSkuValidator"
|
||||||
|
:properties="skuData.properties"
|
||||||
|
:support-big-picture="true"
|
||||||
|
:has-scroll-tab="true"
|
||||||
|
disable-stepper-input
|
||||||
|
reset-stepper-on-hide
|
||||||
|
safe-area-inset-bottom
|
||||||
|
reset-selected-sku-on-hide
|
||||||
|
@buy-clicked="onBuyClicked"
|
||||||
|
@add-cart="onAddCartClicked"
|
||||||
|
>
|
||||||
|
</van-sku>
|
||||||
|
<van-button block type="primary" @click="showBigPictureMode = true">
|
||||||
|
{{ t('bigPicture') }}
|
||||||
|
</van-button>
|
||||||
|
</div>
|
||||||
|
</demo-block>
|
||||||
</demo-section>
|
</demo-section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -156,6 +188,7 @@ export default {
|
|||||||
button1: '积分兑换',
|
button1: '积分兑换',
|
||||||
button2: '买买买',
|
button2: '买买买',
|
||||||
actionsTop: '商品不多,赶快购买吧',
|
actionsTop: '商品不多,赶快购买吧',
|
||||||
|
bigPicture: 'sku大图模式',
|
||||||
},
|
},
|
||||||
'en-US': {
|
'en-US': {
|
||||||
title2: 'Custom Stepper Related Config',
|
title2: 'Custom Stepper Related Config',
|
||||||
@ -164,6 +197,7 @@ export default {
|
|||||||
button1: 'Button',
|
button1: 'Button',
|
||||||
button2: 'Button',
|
button2: 'Button',
|
||||||
actionsTop: 'Action top info',
|
actionsTop: 'Action top info',
|
||||||
|
bigPicture: 'sku big picture mode',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -176,6 +210,7 @@ export default {
|
|||||||
showCustom: false,
|
showCustom: false,
|
||||||
showStepper: false,
|
showStepper: false,
|
||||||
showSoldout: false,
|
showSoldout: false,
|
||||||
|
showBigPictureMode: false,
|
||||||
closeOnClickOverlay: true,
|
closeOnClickOverlay: true,
|
||||||
customSkuValidator: () => '请选择xxx',
|
customSkuValidator: () => '请选择xxx',
|
||||||
customStepperConfig: {
|
customStepperConfig: {
|
||||||
|
@ -56,6 +56,10 @@
|
|||||||
min-height: 96px;
|
min-height: 96px;
|
||||||
padding: @padding-sm 20px @padding-sm @padding-xs;
|
padding: @padding-sm 20px @padding-sm @padding-xs;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
|
&--no-padding {
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,6 +127,92 @@
|
|||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__picture {
|
||||||
|
margin-right: 0;
|
||||||
|
|
||||||
|
&-item {
|
||||||
|
position: relative;
|
||||||
|
flex: 0 0 110px;
|
||||||
|
width: 110px;
|
||||||
|
height: 150px;
|
||||||
|
margin: 0 4px 6px 0;
|
||||||
|
color: @text-color;
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0);
|
||||||
|
border-radius: @border-radius-md;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: @sku-item-background-color;
|
||||||
|
border-radius: @border-radius-md;
|
||||||
|
content: '';
|
||||||
|
}
|
||||||
|
|
||||||
|
&-img {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 1;
|
||||||
|
display: block;
|
||||||
|
width: 110px;
|
||||||
|
height: 110px;
|
||||||
|
object-fit: cover;
|
||||||
|
border-radius: @border-radius-md @border-radius-md 0 0;
|
||||||
|
|
||||||
|
&-icon {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 3;
|
||||||
|
width: 18px;
|
||||||
|
height: 19px;
|
||||||
|
opacity: 1 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-name {
|
||||||
|
position: absolute;
|
||||||
|
top: 110px;
|
||||||
|
left: 0;
|
||||||
|
z-index: 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 110px;
|
||||||
|
height: 40px;
|
||||||
|
padding: @padding-base;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--active {
|
||||||
|
color: @red;
|
||||||
|
border: 1px solid currentColor;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
background: currentColor;
|
||||||
|
opacity: 0.1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--disabled {
|
||||||
|
color: @gray-5;
|
||||||
|
cursor: not-allowed;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
z-index: 2;
|
||||||
|
background: @active-color;
|
||||||
|
opacity: 0.4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&__title {
|
&__title {
|
||||||
padding-bottom: @padding-sm;
|
padding-bottom: @padding-sm;
|
||||||
}
|
}
|
||||||
@ -189,6 +279,44 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&__content {
|
||||||
|
overflow-x: scroll;
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__top {
|
||||||
|
display: inline-flex;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__bottom {
|
||||||
|
display: inline-flex;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__scroll {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
height: 4px;
|
||||||
|
padding-bottom: 16px;
|
||||||
|
|
||||||
|
&__content {
|
||||||
|
position: relative;
|
||||||
|
width: 40px;
|
||||||
|
height: 4px;
|
||||||
|
background: #ebedf0;
|
||||||
|
border-radius: 2px;
|
||||||
|
|
||||||
|
&--active {
|
||||||
|
width: 20px;
|
||||||
|
height: 4px;
|
||||||
|
background: #f44;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&-stepper-stock {
|
&-stepper-stock {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user