mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
[new feature] Sku: update style & add several props (#3875)
This commit is contained in:
parent
e8c528a6f6
commit
503fe5f469
@ -120,9 +120,11 @@ export default {
|
||||
| v-model | Whether to show sku | `boolean` | `false` |
|
||||
| sku | Sku data | `object` | - |
|
||||
| goods | Goods info | `object` | - |
|
||||
| goods-id | Goods id | `string | number` | - |
|
||||
| goods-id | Goods id | `string | `number` | - |
|
||||
| price-tag | Tag behind the price | `string` | - |
|
||||
| hide-stock | Whether to hide stock | `boolean` | `false` |
|
||||
| hide-quota-text | Whether to hide quota text | `boolean` | `false` |
|
||||
| hide-selected-text | Whether to hide selected text | `boolean` | `false` |
|
||||
| show-add-cart-btn | Whether to show cart button | `boolean` | `true` |
|
||||
| buy-text | Buy button text | `string` | - | - |
|
||||
| add-cart-text | Add cart button text | `string` | - | - |
|
||||
@ -263,7 +265,13 @@ customStepperConfig: {
|
||||
Toast('not enough stock');
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
// custom callback when stepper value change
|
||||
handleStepperChange: currentValue => {},
|
||||
// stock
|
||||
stockNum: 1999,
|
||||
// stock fomatter
|
||||
stockFormatter: stockNum => {},
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -123,8 +123,10 @@ export default {
|
||||
| sku | 商品sku数据 | `object` | - | - |
|
||||
| goods | 商品信息 | `object` | - | - |
|
||||
| goods-id | 商品 id | `string | number` | - | - |
|
||||
| price-tag | 显示在价格后面的标签 | `string` | - | - |
|
||||
| hide-stock | 是否显示商品剩余库存 | `boolean` | `false` | - |
|
||||
| hide-quota-text | 是否显示限购提示 | `boolean` | `false` | 1.4.8 |
|
||||
| hide-selected-text | 是否隐藏已选提示 | `boolean` | `false` | - |
|
||||
| show-add-cart-btn | 是否显示加入购物车按钮 | `boolean` | `true` | - |
|
||||
| buy-text | 购买按钮文字 | `string` | `立即购买` | - |
|
||||
| add-cart-text | 加入购物车按钮文字 | `string` | `加入购物车` | - |
|
||||
@ -275,7 +277,13 @@ customStepperConfig: {
|
||||
Toast('库存不够了');
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
// 步进器变化的回调
|
||||
handleStepperChange: currentValue => {},
|
||||
// 库存
|
||||
stockNum: 1999,
|
||||
// 格式化库存
|
||||
stockFormatter: stockNum => {},
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -4,6 +4,7 @@ import Popup from '../popup';
|
||||
import Toast from '../toast';
|
||||
import ImagePreview from '../image-preview';
|
||||
import SkuHeader from './components/SkuHeader';
|
||||
import SkuHeaderItem from './components/SkuHeaderItem';
|
||||
import SkuRow from './components/SkuRow';
|
||||
import SkuRowItem from './components/SkuRowItem';
|
||||
import SkuStepper from './components/SkuStepper';
|
||||
@ -19,6 +20,7 @@ const { QUOTA_LIMIT } = LIMIT_TYPE;
|
||||
export default createComponent({
|
||||
props: {
|
||||
sku: Object,
|
||||
priceTag: String,
|
||||
goods: Object,
|
||||
value: Boolean,
|
||||
buyText: String,
|
||||
@ -28,6 +30,7 @@ export default createComponent({
|
||||
stepperTitle: String,
|
||||
getContainer: Function,
|
||||
hideQuotaText: Boolean,
|
||||
hideSelectedText: Boolean,
|
||||
resetStepperOnHide: Boolean,
|
||||
customSkuValidator: Function,
|
||||
closeOnClickOverlay: Boolean,
|
||||
@ -83,10 +86,8 @@ export default createComponent({
|
||||
show(val) {
|
||||
this.$emit('input', val);
|
||||
if (!val) {
|
||||
const selectedSkuValues = getSelectedSkuValues(this.sku.tree, this.selectedSku);
|
||||
|
||||
this.$emit('sku-close', {
|
||||
selectedSkuValues,
|
||||
selectedSkuValues: this.selectedSkuValues,
|
||||
selectedNum: this.selectedNum,
|
||||
selectedSkuComb: this.selectedSkuComb
|
||||
});
|
||||
@ -114,7 +115,6 @@ export default createComponent({
|
||||
skuGroupClass() {
|
||||
return [
|
||||
'van-sku-group-container',
|
||||
'van-hairline--bottom',
|
||||
{
|
||||
'van-sku-group-container--hide-soldout': !this.showSoldoutSku
|
||||
}
|
||||
@ -160,6 +160,10 @@ export default createComponent({
|
||||
return null;
|
||||
},
|
||||
|
||||
selectedSkuValues() {
|
||||
return getSelectedSkuValues(this.skuTree, this.selectedSku);
|
||||
},
|
||||
|
||||
price() {
|
||||
if (this.selectedSkuComb) {
|
||||
return (this.selectedSkuComb.price / 100).toFixed(2);
|
||||
@ -168,6 +172,13 @@ export default createComponent({
|
||||
return this.sku.price;
|
||||
},
|
||||
|
||||
originPrice() {
|
||||
if (this.selectedSkuComb && this.selectedSkuComb.origin_price) {
|
||||
return (this.selectedSkuComb.origin_price / 100).toFixed(2);
|
||||
}
|
||||
return this.sku.origin_price;
|
||||
},
|
||||
|
||||
skuTree() {
|
||||
return this.sku.tree || [];
|
||||
},
|
||||
@ -191,6 +202,53 @@ export default createComponent({
|
||||
}
|
||||
|
||||
return imageList;
|
||||
},
|
||||
|
||||
stock() {
|
||||
const { stockNum } = this.customStepperConfig;
|
||||
if (stockNum !== undefined) {
|
||||
return stockNum;
|
||||
}
|
||||
if (this.selectedSkuComb) {
|
||||
return this.selectedSkuComb.stock_num;
|
||||
}
|
||||
return this.sku.stock_num;
|
||||
},
|
||||
|
||||
stockText() {
|
||||
const { stockFormatter } = this.customStepperConfig;
|
||||
if (stockFormatter) return stockFormatter(this.stock);
|
||||
|
||||
return `剩余 ${this.stock}件`;
|
||||
},
|
||||
|
||||
quotaText() {
|
||||
const { quotaText, hideQuotaText } = this.customStepperConfig;
|
||||
|
||||
if (hideQuotaText) return '';
|
||||
|
||||
let text = '';
|
||||
|
||||
if (quotaText) {
|
||||
text = quotaText;
|
||||
} else if (this.quota > 0) {
|
||||
text = `每人限购${this.quota}件`;
|
||||
}
|
||||
|
||||
return text;
|
||||
},
|
||||
|
||||
selectedText() {
|
||||
if (this.selectedSkuComb) {
|
||||
return `已选 ${this.selectedSkuValues.map(item => item.name).join(';')}`;
|
||||
}
|
||||
|
||||
const unselected = this.skuTree
|
||||
.filter(item => this.selectedSku[item.k_s] === UNSELECTED_SKU_VALUE_ID)
|
||||
.map(item => item.k)
|
||||
.join(';');
|
||||
|
||||
return `选择 ${unselected}`;
|
||||
}
|
||||
},
|
||||
|
||||
@ -378,6 +436,7 @@ export default createComponent({
|
||||
sku,
|
||||
goods,
|
||||
price,
|
||||
originPrice,
|
||||
skuEventBus,
|
||||
selectedSku,
|
||||
selectedNum,
|
||||
@ -388,6 +447,7 @@ export default createComponent({
|
||||
|
||||
const slotsProps = {
|
||||
price,
|
||||
originPrice,
|
||||
selectedNum,
|
||||
skuEventBus,
|
||||
selectedSku,
|
||||
@ -398,9 +458,25 @@ export default createComponent({
|
||||
const Header = slots('sku-header') || (
|
||||
<SkuHeader sku={sku} goods={goods} skuEventBus={skuEventBus} selectedSku={selectedSku}>
|
||||
{slots('sku-header-price') || (
|
||||
<div class="van-sku__goods-price">
|
||||
<span class="van-sku__price-symbol">¥</span>
|
||||
<span class="van-sku__price-num">{price}</span>
|
||||
<div>
|
||||
<div class="van-sku__goods-price">
|
||||
<span class="van-sku__price-symbol">¥</span>
|
||||
<span class="van-sku__price-num">{price}</span>
|
||||
{this.priceTag && <span class="van-sku__price-tag">{this.priceTag}</span>}
|
||||
</div>
|
||||
{originPrice && (
|
||||
<SkuHeaderItem>原价 ¥{originPrice}</SkuHeaderItem>
|
||||
)}
|
||||
{!this.hideStock && (
|
||||
<SkuHeaderItem>
|
||||
<span class="van-sku__stock">{this.stockText}</span>
|
||||
{!hideQuotaText && this.quotaText && <span class="van-sku__quota">({this.quotaText})</span>}
|
||||
</SkuHeaderItem>
|
||||
)}
|
||||
{this.hasSku && !this.hideSelectedText && (
|
||||
<SkuHeaderItem>{this.selectedText}</SkuHeaderItem>
|
||||
)}
|
||||
{slots('sku-header-extra')}
|
||||
</div>
|
||||
)}
|
||||
</SkuHeader>
|
||||
@ -429,16 +505,14 @@ export default createComponent({
|
||||
const Stepper = slots('sku-stepper') || (
|
||||
<SkuStepper
|
||||
ref="skuStepper"
|
||||
stock={this.stock}
|
||||
quota={this.quota}
|
||||
hideStock={this.hideStock}
|
||||
quotaUsed={this.quotaUsed}
|
||||
skuEventBus={skuEventBus}
|
||||
selectedNum={selectedNum}
|
||||
selectedSku={selectedSku}
|
||||
stepperTitle={stepperTitle}
|
||||
skuStockNum={sku.stock_num}
|
||||
hideQuotaText={hideQuotaText}
|
||||
selectedSkuComb={selectedSkuComb}
|
||||
disableStepperInput={this.disableStepperInput}
|
||||
customStepperConfig={this.customStepperConfig}
|
||||
onChange={event => {
|
||||
@ -472,6 +546,7 @@ export default createComponent({
|
||||
class="van-sku-container"
|
||||
getContainer={this.getContainer}
|
||||
closeOnClickOverlay={this.closeOnClickOverlay}
|
||||
round
|
||||
>
|
||||
{Header}
|
||||
<div class="van-sku-body" style={this.bodyStyle}>
|
||||
|
@ -50,10 +50,9 @@ function SkuHeader(
|
||||
<img src={goodsImg} />
|
||||
</div>
|
||||
<div class={bem('goods-info')}>
|
||||
<div class="van-sku__goods-name van-ellipsis">{goods.title}</div>
|
||||
{slots.default && slots.default()}
|
||||
<Icon
|
||||
name="close"
|
||||
name="clear"
|
||||
class="van-sku__close-icon"
|
||||
onClick={() => {
|
||||
skuEventBus.$emit('sku:close');
|
||||
|
25
src/sku/components/SkuHeaderItem.tsx
Normal file
25
src/sku/components/SkuHeaderItem.tsx
Normal file
@ -0,0 +1,25 @@
|
||||
import { createNamespace } from '../../utils';
|
||||
import { inherit } from '../../utils/functional';
|
||||
|
||||
// Types
|
||||
import { CreateElement, RenderContext } from 'vue/types';
|
||||
import { DefaultSlots } from '../../utils/types';
|
||||
|
||||
export type SkuHeaderItemProps = {};
|
||||
|
||||
const [createComponent, bem] = createNamespace('sku-header-item');
|
||||
|
||||
function SkuHeader(
|
||||
h: CreateElement,
|
||||
props: SkuHeaderItemProps,
|
||||
slots: DefaultSlots,
|
||||
ctx: RenderContext<SkuHeaderItemProps>
|
||||
) {
|
||||
return (
|
||||
<div class={bem()} {...inherit(ctx)}>
|
||||
{slots.default && slots.default()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default createComponent<SkuHeaderItemProps>(SkuHeader);
|
@ -18,20 +18,16 @@ export default createComponent({
|
||||
data() {
|
||||
return {
|
||||
// 正在上传的图片 base64
|
||||
paddingImg: ''
|
||||
paddingImg: '',
|
||||
uploadFail: false
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
imgList() {
|
||||
return this.value && !this.paddingImg ? [this.value] : [];
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
afterReadFile(file) {
|
||||
// 上传文件
|
||||
this.paddingImg = file.content;
|
||||
this.uploadFail = false;
|
||||
this.uploadImg(file.file, file.content)
|
||||
.then(img => {
|
||||
this.$emit('input', img);
|
||||
@ -40,23 +36,53 @@ export default createComponent({
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
this.paddingImg = '';
|
||||
this.uploadFail = true;
|
||||
});
|
||||
},
|
||||
|
||||
onOversize() {
|
||||
this.$toast(`最大可上传图片为${this.maxSize}MB,请尝试压缩图片尺寸`);
|
||||
},
|
||||
|
||||
renderUploader(content, disabled = false) {
|
||||
return (
|
||||
<Uploader
|
||||
class={bem('uploader')}
|
||||
disabled={disabled}
|
||||
afterRead={this.afterReadFile}
|
||||
maxSize={this.maxSize * 1024 * 1024}
|
||||
onOversize={this.onOversize}
|
||||
>
|
||||
<div class={bem('img')}>
|
||||
{content}
|
||||
</div>
|
||||
</Uploader>
|
||||
);
|
||||
},
|
||||
|
||||
renderMask() {
|
||||
return (
|
||||
<div class={bem('mask')}>
|
||||
{this.uploadFail
|
||||
? (
|
||||
[
|
||||
<Icon name="warning-o" size="20px" />,
|
||||
<div class={bem('warn-text')}>上传失败<br />重新上传</div>
|
||||
]
|
||||
) : (
|
||||
<Loading type="spinner" size="20px" color="white" />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
render(h) {
|
||||
const { imgList, paddingImg } = this;
|
||||
|
||||
const ImageList = (paddingImg || imgList.length > 0) && (
|
||||
<div class="van-clearfix">
|
||||
{imgList.map(img => (
|
||||
<div class={bem('img')}>
|
||||
<img src={img} />
|
||||
return (
|
||||
<div class={bem()}>
|
||||
{this.value && this.renderUploader(
|
||||
[
|
||||
<img src={this.value} />,
|
||||
<Icon
|
||||
name="clear"
|
||||
class={bem('delete')}
|
||||
@ -64,40 +90,24 @@ export default createComponent({
|
||||
this.$emit('input', '');
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
{paddingImg && (
|
||||
<div class={bem('img')}>
|
||||
<img src={paddingImg} />
|
||||
<Loading type="spinner" class={bem('uploading')} />
|
||||
],
|
||||
true
|
||||
)}
|
||||
|
||||
{this.paddingImg && this.renderUploader(
|
||||
[
|
||||
<img src={this.paddingImg} />,
|
||||
this.renderMask()
|
||||
],
|
||||
!this.uploadFail
|
||||
)}
|
||||
|
||||
{!this.value && !this.paddingImg && this.renderUploader(
|
||||
<div class={bem('trigger')}>
|
||||
<Icon name="photograph" size="22px" />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<div class={bem()}>
|
||||
<Uploader
|
||||
disabled={!!paddingImg}
|
||||
afterRead={this.afterReadFile}
|
||||
maxSize={this.maxSize * 1024 * 1024}
|
||||
onOversize={this.onOversize}
|
||||
>
|
||||
<div class={bem('header')}>
|
||||
{paddingImg ? (
|
||||
<div>正在上传...</div>
|
||||
) : (
|
||||
[
|
||||
<Icon name="photograph" />,
|
||||
<span class="label">{this.value ? '重拍' : '拍照'} 或 </span>,
|
||||
<Icon name="photo" />,
|
||||
<span class="label">{this.value ? '重新选择照片' : '选择照片'}</span>
|
||||
]
|
||||
)}
|
||||
</div>
|
||||
</Uploader>
|
||||
{ImageList}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
@ -127,6 +127,7 @@ export default createComponent({
|
||||
{this.messages.map((message, index) => (message.type === 'image' ? (
|
||||
<Cell
|
||||
class={bem('image-cell')}
|
||||
value-class={bem('image-cell-value')}
|
||||
label="仅限一张"
|
||||
title={message.name}
|
||||
key={`${this.goodsId}-${index}`}
|
||||
|
@ -19,8 +19,8 @@ function SkuRow(
|
||||
ctx: RenderContext<SkuRowProps>
|
||||
) {
|
||||
return (
|
||||
<div class={bem()} {...inherit(ctx)}>
|
||||
<div class={bem('title')}>{props.skuRow.k}:</div>
|
||||
<div class={[bem(), 'van-hairline--bottom']} {...inherit(ctx)}>
|
||||
<div class={bem('title')}>{props.skuRow.k}</div>
|
||||
{slots.default && slots.default()}
|
||||
</div>
|
||||
);
|
||||
|
@ -37,6 +37,7 @@ export default createComponent({
|
||||
|
||||
render(h) {
|
||||
const choosed = this.skuValue.id === this.selectedSku[this.skuKeyStr];
|
||||
const imgUrl = this.skuValue.imgUrl || this.skuValue.img_url;
|
||||
|
||||
return (
|
||||
<span
|
||||
@ -49,7 +50,8 @@ export default createComponent({
|
||||
]}
|
||||
onClick={this.onSelect}
|
||||
>
|
||||
{this.skuValue.name}
|
||||
{imgUrl && <img class="van-sku-row__item-img" src={imgUrl} />}
|
||||
<span class="van-sku-row__item-name">{this.skuValue.name}</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
@ -7,14 +7,11 @@ const { QUOTA_LIMIT, STOCK_LIMIT } = LIMIT_TYPE;
|
||||
|
||||
export default createComponent({
|
||||
props: {
|
||||
hideStock: Boolean,
|
||||
selectedSku: Object,
|
||||
stock: Number,
|
||||
skuEventBus: Object,
|
||||
skuStockNum: Number,
|
||||
selectedNum: Number,
|
||||
stepperTitle: String,
|
||||
hideQuotaText: Boolean,
|
||||
selectedSkuComb: Object,
|
||||
disableStepperInput: Boolean,
|
||||
customStepperConfig: Object,
|
||||
quota: {
|
||||
@ -48,40 +45,6 @@ export default createComponent({
|
||||
},
|
||||
|
||||
computed: {
|
||||
stock() {
|
||||
const { stockNum } = this.customStepperConfig;
|
||||
if (stockNum !== undefined) {
|
||||
return stockNum;
|
||||
}
|
||||
if (this.selectedSkuComb) {
|
||||
return this.selectedSkuComb.stock_num;
|
||||
}
|
||||
return this.skuStockNum;
|
||||
},
|
||||
|
||||
stockText() {
|
||||
const { stockFormatter } = this.customStepperConfig;
|
||||
if (stockFormatter) return stockFormatter(this.stock);
|
||||
|
||||
return `剩余${this.stock}件`;
|
||||
},
|
||||
|
||||
quotaText() {
|
||||
const { quotaText, hideQuotaText } = this.customStepperConfig;
|
||||
|
||||
if (hideQuotaText) return '';
|
||||
|
||||
let text = '';
|
||||
|
||||
if (quotaText) {
|
||||
text = quotaText;
|
||||
} else if (this.quota > 0) {
|
||||
text = `每人限购${this.quota}件`;
|
||||
}
|
||||
|
||||
return text;
|
||||
},
|
||||
|
||||
stepperLimit() {
|
||||
const quotaLimit = this.quota - this.quotaUsed;
|
||||
let limit;
|
||||
@ -125,7 +88,7 @@ export default createComponent({
|
||||
return (
|
||||
<div class="van-sku-stepper-stock">
|
||||
<div class="van-sku-stepper-container">
|
||||
<div class="van-sku__stepper-title">{this.stepperTitle || '购买数量'}:</div>
|
||||
<div class="van-sku__stepper-title">{this.stepperTitle || '购买数量'}</div>
|
||||
<Stepper
|
||||
vModel={this.currentNum}
|
||||
class="van-sku__stepper"
|
||||
@ -135,10 +98,6 @@ export default createComponent({
|
||||
onChange={this.onChange}
|
||||
/>
|
||||
</div>
|
||||
{!this.hideStock && <div class="van-sku__stock">{this.stockText}</div>}
|
||||
{!this.hideQuotaText && this.quotaText && (
|
||||
<div class="van-sku__quota">{this.quotaText}</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import Sku from './Sku';
|
||||
import SkuActions from './components/SkuActions';
|
||||
import SkuHeader from './components/SkuHeader';
|
||||
import SkuHeaderItem from './components/SkuHeaderItem';
|
||||
import SkuMessages from './components/SkuMessages';
|
||||
import SkuStepper from './components/SkuStepper';
|
||||
import SkuRow from './components/SkuRow';
|
||||
@ -10,6 +11,7 @@ import constants from './constants';
|
||||
|
||||
Sku.SkuActions = SkuActions;
|
||||
Sku.SkuHeader = SkuHeader;
|
||||
Sku.SkuHeaderItem = SkuHeaderItem;
|
||||
Sku.SkuMessages = SkuMessages;
|
||||
Sku.SkuStepper = SkuStepper;
|
||||
Sku.SkuRow = SkuRow;
|
||||
|
@ -3,6 +3,10 @@
|
||||
|
||||
.van-sku {
|
||||
&-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
height: 70%;
|
||||
max-height: max-content; /* avoid androiod keyboard cover fields */
|
||||
overflow-y: visible;
|
||||
font-size: 14px;
|
||||
@ -10,6 +14,7 @@
|
||||
}
|
||||
|
||||
&-body {
|
||||
flex: 1 1 auto;
|
||||
max-height: 350px;
|
||||
overflow-y: scroll;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
@ -26,11 +31,11 @@
|
||||
&__img-wrap {
|
||||
position: relative;
|
||||
float: left;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
margin-top: -10px;
|
||||
width: 96px;
|
||||
height: 96px;
|
||||
margin: 12px 0 12px;
|
||||
background: @background-color;
|
||||
border-radius: 2px;
|
||||
border-radius: 4px;
|
||||
|
||||
img {
|
||||
position: absolute;
|
||||
@ -45,37 +50,51 @@
|
||||
}
|
||||
|
||||
&__goods-info {
|
||||
box-sizing: border-box;
|
||||
min-height: 82px;
|
||||
padding: 10px 60px 10px 10px;
|
||||
min-height: 96px;
|
||||
padding: 12px 36px 12px 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
&__goods-name {
|
||||
&-header-item {
|
||||
margin-top: 8px;
|
||||
color: @gray-dark;
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
&__price-symbol {
|
||||
vertical-align: middle;
|
||||
font-size: 16px;
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
|
||||
&__price-num {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
font-size: 22px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
&__goods-price {
|
||||
margin-top: 10px;
|
||||
color: @red;
|
||||
}
|
||||
|
||||
&__price-tag {
|
||||
display: inline-block;
|
||||
margin-left: 8px;
|
||||
padding: 0 5px;
|
||||
color: @red;
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
vertical-align: middle;
|
||||
background-color: @sku-price-tag-color;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
&__close-icon {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
top: 12px;
|
||||
right: 15px;
|
||||
color: @gray-dark;
|
||||
color: @sku-icon-gray-color;
|
||||
font-size: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
@ -93,40 +112,53 @@
|
||||
|
||||
/* sku row */
|
||||
&-row {
|
||||
margin: 0 15px 10px 0;
|
||||
margin: 0 3px 12px 0;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
&__title {
|
||||
padding-bottom: 10px;
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
|
||||
&__item {
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
min-width: 52px;
|
||||
height: 28px;
|
||||
margin: 0 10px 10px 0;
|
||||
padding: 5px 9px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 40px;
|
||||
margin: 0 12px 12px 0;
|
||||
color: @text-color;
|
||||
font-size: 12px;
|
||||
font-size: 13px;
|
||||
line-height: 16px;
|
||||
text-align: center;
|
||||
border: 1px solid @gray-dark;
|
||||
border-radius: 3px;
|
||||
vertical-align: middle;
|
||||
background: @sku-item-background-color;
|
||||
border-radius: 4px;
|
||||
|
||||
&-img {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
margin: 4px 0 4px 4px;
|
||||
object-fit: cover;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
&-name {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
&--active {
|
||||
color: @white;
|
||||
background: @red;
|
||||
border-color: @red;
|
||||
color: @red;
|
||||
background: @sku-item-active-background-color;
|
||||
}
|
||||
|
||||
&--disabled {
|
||||
color: @gray;
|
||||
background: @active-color;
|
||||
border-color: @border-color;
|
||||
|
||||
.van-sku-row__item-img {
|
||||
opacity: .3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -176,6 +208,7 @@
|
||||
}
|
||||
|
||||
.van-cell__value {
|
||||
overflow: visible;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
@ -184,35 +217,23 @@
|
||||
&-img-uploader {
|
||||
display: inline-block;
|
||||
|
||||
&__header {
|
||||
padding: 0 10px;
|
||||
color: @text-color;
|
||||
font-size: 12px;
|
||||
line-height: 24px;
|
||||
border: 1px solid @border-color;
|
||||
border-radius: 3px;
|
||||
|
||||
.van-icon {
|
||||
top: 3px;
|
||||
margin-right: 5px;
|
||||
font-size: 14px;
|
||||
}
|
||||
&__uploader {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
&__img {
|
||||
position: relative;
|
||||
float: left;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
margin: 10px 10px 0 0;
|
||||
border: 1px solid @border-color;
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
margin-right: 8px;
|
||||
background: @sku-item-background-color;
|
||||
border-radius: 2px;
|
||||
|
||||
img {
|
||||
position: relative;
|
||||
top: 50%;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
transform: translateY(-50%);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
|
||||
@ -222,7 +243,8 @@
|
||||
right: -14px;
|
||||
z-index: 1;
|
||||
padding: 6px;
|
||||
color: @red;
|
||||
color: @sku-upload-mask-color;
|
||||
opacity: .8;
|
||||
|
||||
&::before {
|
||||
background-color: @white;
|
||||
@ -230,15 +252,33 @@
|
||||
}
|
||||
}
|
||||
|
||||
&__uploading {
|
||||
&__mask {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
color: white;
|
||||
background: @sku-upload-mask-color;
|
||||
}
|
||||
|
||||
&__warn-text {
|
||||
margin-top: 6px;
|
||||
font-size: 12px;
|
||||
line-height: 14px;
|
||||
}
|
||||
|
||||
&__trigger {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
color: @sku-icon-gray-color;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -651,3 +651,10 @@
|
||||
@uploader-file-icon-color: @gray-darker;
|
||||
@uploader-file-name-font-size: @font-size-sm;
|
||||
@uploader-file-name-text-color: @gray-darker;
|
||||
|
||||
// Sku
|
||||
@sku-price-tag-color: rgba(227, 20, 54, .1);
|
||||
@sku-item-background-color: #f7f8fa;
|
||||
@sku-item-active-background-color: rgba(227, 20, 54, .1);
|
||||
@sku-icon-gray-color: #dcdde0;
|
||||
@sku-upload-mask-color: rgba(50, 50, 51, .8);
|
||||
|
Loading…
x
Reference in New Issue
Block a user