mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
chore: merge branch "dev"
This commit is contained in:
commit
9302cae9ba
@ -1,5 +1,47 @@
|
||||
# Changelog
|
||||
|
||||
### [v2.3.0-beta.1](https://github.com/youzan/vant/tree/v2.3.0-beta.1)
|
||||
`2019-11-30`
|
||||
|
||||
**Style**
|
||||
|
||||
Upgrading the style of business components:
|
||||
|
||||
- AddressEdit
|
||||
- Card
|
||||
- ContactList
|
||||
- ContactCard
|
||||
- ContactEdit
|
||||
- SubmitBar
|
||||
|
||||
**Features**
|
||||
|
||||
- Card: add price-top slot [\#5134](https://github.com/youzan/vant/pull/5134)
|
||||
- Circle: add stroke-linecap prop [\#5087](https://github.com/youzan/vant/pull/5087)
|
||||
- CountDown: support SS and S format [\#5154](https://github.com/youzan/vant/pull/5154)
|
||||
- Sku: add new startSaleNum prop [\#5105](https://github.com/youzan/vant/pull/5105)
|
||||
- SubmitBar: add text-align prop [\#5130](https://github.com/youzan/vant/pull/5130)
|
||||
- AddressList: add default-tag-text prop [\#5106](https://github.com/youzan/vant/pull/5106)
|
||||
- ContactList: add default-tag-text prop [\#5089](https://github.com/youzan/vant/pull/5089)
|
||||
- ContactCard: add show-set-default prop [\#5083](https://github.com/youzan/vant/pull/5083)
|
||||
- Toast: improve type definitions [\#5086](https://github.com/youzan/vant/pull/5086)
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
- fix TreeSelect should sync value before trigger click-item event [\#5153](https://github.com/youzan/vant/pull/5153)
|
||||
- fix TouchEmulator compatibility issues on firefox [\#5118](https://github.com/youzan/vant/pull/5118)
|
||||
- fix Card allow use bottom slot without price or num [\#5116](https://github.com/youzan/vant/pull/5116)
|
||||
- fix NumberKeyboard should not trigger blur event when hidden [\#5110](https://github.com/youzan/vant/pull/5110)
|
||||
|
||||
|
||||
### [v2.2.15](https://github.com/youzan/vant/tree/v2.2.15)
|
||||
`2019-11-28`
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
- fix List incorrect list status in some cases
|
||||
|
||||
|
||||
### [v2.2.14](https://github.com/youzan/vant/tree/v2.2.14)
|
||||
`2019-11-22`
|
||||
|
||||
|
@ -10,6 +10,49 @@ Vant 遵循 [Semver](https://semver.org/lang/zh-CN/) 语义化版本规范。
|
||||
- 次版本号:每隔一至二个月发布,包含新特性和较大的功能更新,向下兼容。
|
||||
- 主版本号:发布时间不定,包含不兼容更新,预计下一个主版本会与 Vue 3.0 同期发布。
|
||||
|
||||
|
||||
### [v2.3.0-beta.1](https://github.com/youzan/vant/tree/v2.3.0-beta.1)
|
||||
`2019-11-30`
|
||||
|
||||
**Style**
|
||||
|
||||
在 2.3.0 版本中,我们对业务组件的样式进行了全新升级,涉及以下组件:
|
||||
|
||||
- AddressEdit
|
||||
- Card
|
||||
- ContactList
|
||||
- ContactCard
|
||||
- ContactEdit
|
||||
- SubmitBar
|
||||
|
||||
**Features**
|
||||
|
||||
- Card: 新增 price-top 插槽 [\#5134](https://github.com/youzan/vant/pull/5134)
|
||||
- Circle: 新增 stroke-linecap 属性 [\#5087](https://github.com/youzan/vant/pull/5087)
|
||||
- CountDown: 支持 SS 和 S 格式 [\#5154](https://github.com/youzan/vant/pull/5154)
|
||||
- Sku: 新增 new startSaleNum 属性 [\#5105](https://github.com/youzan/vant/pull/5105)
|
||||
- SubmitBar: 新增 text-align 属性 [\#5130](https://github.com/youzan/vant/pull/5130)
|
||||
- AddressList: 新增 default-tag-text 属性 [\#5106](https://github.com/youzan/vant/pull/5106)
|
||||
- ContactList: 新增 default-tag-text 属性 [\#5089](https://github.com/youzan/vant/pull/5089)
|
||||
- ContactCard: 新增 show-set-default 属性 [\#5083](https://github.com/youzan/vant/pull/5083)
|
||||
- Toast: 完善 TS 类型定义 [\#5086](https://github.com/youzan/vant/pull/5086)
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
- 修复 TreeSelect 事件触发顺序错误的问题 [\#5153](https://github.com/youzan/vant/pull/5153)
|
||||
- 修复 TouchEmulator 在 Firefox 上的兼容性问题 [\#5118](https://github.com/youzan/vant/pull/5118)
|
||||
- 修复 Card 在未使用 price 属性的情况下 bottom 插槽不生效的问题 [\#5116](https://github.com/youzan/vant/pull/5116)
|
||||
- 修复 NumberKeyboard 在隐藏状态下也会触发 blur 事件的问题 [\#5110](https://github.com/youzan/vant/pull/5110)
|
||||
|
||||
|
||||
### [v2.2.15](https://github.com/youzan/vant/tree/v2.2.15)
|
||||
`2019-11-28`
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
- 修复 List 组件在部分情况下加载状态未重置的问题
|
||||
|
||||
|
||||
### [v2.2.14](https://github.com/youzan/vant/tree/v2.2.14)
|
||||
`2019-11-22`
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vant",
|
||||
"version": "2.2.14",
|
||||
"version": "2.3.0-beta.1",
|
||||
"description": "Mobile UI Components built on Vue",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
|
@ -45,7 +45,7 @@ Use slot to custom content.
|
||||
<van-card
|
||||
num="2"
|
||||
title="Title"
|
||||
desc="Description"
|
||||
desc="Description"
|
||||
price="2.00"
|
||||
thumb="https://img.yzcdn.cn/vant/t-thirt.jpg"
|
||||
>
|
||||
@ -94,6 +94,7 @@ Use slot to custom content.
|
||||
| num | Custom num |
|
||||
| price | Custom price |
|
||||
| origin-price | Custom origin price |
|
||||
| price-top | Custom price top |
|
||||
| bottom | Custom price bottom |
|
||||
| thumb | Custom thumb |
|
||||
| tag | Custom thumb tag |
|
||||
|
@ -17,7 +17,7 @@ Vue.use(Card);
|
||||
<van-card
|
||||
num="2"
|
||||
price="2.00"
|
||||
desc="描述信息"
|
||||
desc="描述信息"
|
||||
title="商品标题"
|
||||
thumb="https://img.yzcdn.cn/vant/t-thirt.jpg"
|
||||
/>
|
||||
@ -32,7 +32,7 @@ Vue.use(Card);
|
||||
num="2"
|
||||
tag="标签"
|
||||
price="2.00"
|
||||
desc="描述信息"
|
||||
desc="描述信息"
|
||||
title="商品标题"
|
||||
thumb="https://img.yzcdn.cn/vant/t-thirt.jpg"
|
||||
origin-price="10.00"
|
||||
@ -47,7 +47,7 @@ Vue.use(Card);
|
||||
<van-card
|
||||
num="2"
|
||||
price="2.00"
|
||||
desc="描述信息"
|
||||
desc="描述信息"
|
||||
title="商品标题"
|
||||
thumb="https://img.yzcdn.cn/vant/t-thirt.jpg"
|
||||
>
|
||||
@ -96,6 +96,7 @@ Vue.use(Card);
|
||||
| num | 自定义数量 |
|
||||
| price | 自定义价格 |
|
||||
| origin-price | 自定义商品原价 |
|
||||
| price-top | 自定义价格上方区域 |
|
||||
| bottom | 自定义价格下方区域 |
|
||||
| thumb | 自定义图片 |
|
||||
| tag | 自定义图片角标 |
|
||||
|
@ -22,6 +22,7 @@
|
||||
width: @card-thumb-size;
|
||||
height: @card-thumb-size;
|
||||
margin-right: @padding-xs;
|
||||
border-radius: @card-thumb-border-radius;
|
||||
}
|
||||
|
||||
&__content {
|
||||
@ -29,6 +30,7 @@
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
min-width: 0; /* hack for flex box ellipsis */
|
||||
min-height: @card-thumb-size;
|
||||
|
||||
@ -62,6 +64,11 @@
|
||||
display: inline-block;
|
||||
color: @card-price-color;
|
||||
font-weight: @font-weight-bold;
|
||||
|
||||
&--integer {
|
||||
font-size: @card-price-integer-font-size;
|
||||
font-family: @card-price-font-family;
|
||||
}
|
||||
}
|
||||
|
||||
&__origin-price {
|
||||
@ -74,6 +81,7 @@
|
||||
|
||||
&__num {
|
||||
float: right;
|
||||
color: @card-num-color;
|
||||
}
|
||||
|
||||
&__tag {
|
||||
|
@ -32,6 +32,7 @@ export type CardSlots = DefaultSlots & {
|
||||
bottom?: ScopedSlot;
|
||||
footer?: ScopedSlot;
|
||||
'origin-price'?: ScopedSlot;
|
||||
'price-top'?: ScopedSlot;
|
||||
};
|
||||
|
||||
export type CardEvents = {
|
||||
@ -114,11 +115,22 @@ function Card(
|
||||
}
|
||||
}
|
||||
|
||||
function PriceContent() {
|
||||
const priceArr = props.price!.toString().split('.');
|
||||
return (
|
||||
<div>
|
||||
{props.currency}
|
||||
<span class={bem('price', 'integer')}>{priceArr[0]}</span>.
|
||||
{priceArr[1]}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Price() {
|
||||
if (showPrice) {
|
||||
return (
|
||||
<div class={bem('price')}>
|
||||
{slots.price ? slots.price() : `${props.currency} ${props.price}`}
|
||||
{slots.price ? slots.price() : PriceContent()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -137,7 +149,7 @@ function Card(
|
||||
|
||||
function Num() {
|
||||
if (showNum) {
|
||||
return <div class={bem('num')}>{slots.num ? slots.num() : `x ${props.num}`}</div>;
|
||||
return <div class={bem('num')}>{slots.num ? slots.num() : `x${props.num}`}</div>;
|
||||
}
|
||||
}
|
||||
|
||||
@ -152,11 +164,14 @@ function Card(
|
||||
<div class={bem('header')}>
|
||||
{Thumb()}
|
||||
<div class={bem('content', { centered: props.centered })}>
|
||||
{Title()}
|
||||
{Desc()}
|
||||
{slots.tags && slots.tags()}
|
||||
<div>
|
||||
{Title()}
|
||||
{Desc()}
|
||||
{slots.tags && slots.tags()}
|
||||
</div>
|
||||
{showBottom && (
|
||||
<div class="van-card__bottom">
|
||||
{slots['price-top'] && slots['price-top']()}
|
||||
{Price()}
|
||||
{OriginPrice()}
|
||||
{Num()}
|
||||
|
@ -11,11 +11,15 @@ exports[`renders demo correctly 1`] = `
|
||||
</div>
|
||||
</a>
|
||||
<div class="van-card__content">
|
||||
<div class="van-card__title van-multi-ellipsis--l2">商品名称</div>
|
||||
<div class="van-card__desc van-ellipsis">描述信息</div>
|
||||
<div>
|
||||
<div class="van-card__title van-multi-ellipsis--l2">商品名称</div>
|
||||
<div class="van-card__desc van-ellipsis">描述信息</div>
|
||||
</div>
|
||||
<div class="van-card__bottom">
|
||||
<div class="van-card__price">¥ 2.00</div>
|
||||
<div class="van-card__num">x 2</div>
|
||||
<div class="van-card__price">
|
||||
<div>¥<span class="van-card__price van-card__price--integer">2</span>.00</div>
|
||||
</div>
|
||||
<div class="van-card__num">x2</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -31,12 +35,16 @@ exports[`renders demo correctly 1`] = `
|
||||
<div class="van-card__tag"><span class="van-tag van-tag--mark van-tag--danger">标签</span></div>
|
||||
</a>
|
||||
<div class="van-card__content">
|
||||
<div class="van-card__title van-multi-ellipsis--l2">商品名称</div>
|
||||
<div class="van-card__desc van-ellipsis">描述信息</div>
|
||||
<div>
|
||||
<div class="van-card__title van-multi-ellipsis--l2">商品名称</div>
|
||||
<div class="van-card__desc van-ellipsis">描述信息</div>
|
||||
</div>
|
||||
<div class="van-card__bottom">
|
||||
<div class="van-card__price">¥ 2.00</div>
|
||||
<div class="van-card__price">
|
||||
<div>¥<span class="van-card__price van-card__price--integer">2</span>.00</div>
|
||||
</div>
|
||||
<div class="van-card__origin-price">¥ 10.00</div>
|
||||
<div class="van-card__num">x 2</div>
|
||||
<div class="van-card__num">x2</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -51,16 +59,20 @@ exports[`renders demo correctly 1`] = `
|
||||
</div>
|
||||
</a>
|
||||
<div class="van-card__content">
|
||||
<div class="van-card__title van-multi-ellipsis--l2">商品名称</div>
|
||||
<div class="van-card__desc van-ellipsis">描述信息</div>
|
||||
<div><span class="van-tag van-tag--plain van-tag--danger van-hairline--surround" style="margin-right: 5px;">
|
||||
<div>
|
||||
<div class="van-card__title van-multi-ellipsis--l2">商品名称</div>
|
||||
<div class="van-card__desc van-ellipsis">描述信息</div>
|
||||
<div><span class="van-tag van-tag--plain van-tag--danger van-hairline--surround" style="margin-right: 5px;">
|
||||
标签
|
||||
</span> <span class="van-tag van-tag--plain van-tag--danger van-hairline--surround">
|
||||
标签
|
||||
</span></div>
|
||||
</div>
|
||||
<div class="van-card__bottom">
|
||||
<div class="van-card__price">¥ 2.00</div>
|
||||
<div class="van-card__num">x 2</div>
|
||||
<div class="van-card__price">
|
||||
<div>¥<span class="van-card__price van-card__price--integer">2</span>.00</div>
|
||||
</div>
|
||||
<div class="van-card__num">x2</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -4,6 +4,7 @@ exports[`render bottom slot 1`] = `
|
||||
<div class="van-card">
|
||||
<div class="van-card__header">
|
||||
<div class="van-card__content">
|
||||
<div></div>
|
||||
<div class="van-card__bottom">Custom Bottom</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -14,6 +15,7 @@ exports[`render origin-price slot 1`] = `
|
||||
<div class="van-card">
|
||||
<div class="van-card__header">
|
||||
<div class="van-card__content">
|
||||
<div></div>
|
||||
<div class="van-card__bottom">
|
||||
<div class="van-card__origin-price">Custom Origin Price</div>
|
||||
</div>
|
||||
@ -26,6 +28,7 @@ exports[`render price & num slot 1`] = `
|
||||
<div class="van-card">
|
||||
<div class="van-card__header">
|
||||
<div class="van-card__content">
|
||||
<div></div>
|
||||
<div class="van-card__bottom">
|
||||
<div class="van-card__price">Custom Price</div>
|
||||
<div class="van-card__num">Custom Num</div>
|
||||
@ -38,7 +41,9 @@ exports[`render price & num slot 1`] = `
|
||||
exports[`render thumb & tag slot 1`] = `
|
||||
<div class="van-card">
|
||||
<div class="van-card__header"><a class="van-card__thumb">Custom Thumb<div class="van-card__tag">Custom Tag</div></a>
|
||||
<div class="van-card__content"></div>
|
||||
<div class="van-card__content">
|
||||
<div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@ -46,7 +51,21 @@ exports[`render thumb & tag slot 1`] = `
|
||||
exports[`render title & desc slot 1`] = `
|
||||
<div class="van-card">
|
||||
<div class="van-card__header">
|
||||
<div class="van-card__content">Custom TitleCustom desc</div>
|
||||
<div class="van-card__content">
|
||||
<div>Custom TitleCustom desc</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`render price & price-top slot 1`] = `
|
||||
<div class="van-card">
|
||||
<div class="van-card__header">
|
||||
<div class="van-card__content">
|
||||
<div></div>
|
||||
<div class="van-card__bottom">Custom Price-top<div class="van-card__price">Custom Price</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
@ -94,3 +94,14 @@ test('render title & desc slot', () => {
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('render price & price-top slot', () => {
|
||||
const wrapper = mount(Card, {
|
||||
scopedSlots: {
|
||||
price: () => 'Custom Price',
|
||||
'price-top': () => 'Custom Price-top'
|
||||
}
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
@ -42,7 +42,7 @@ export default {
|
||||
<van-count-down
|
||||
millisecond
|
||||
:time="time"
|
||||
format="HH:mm:ss:SSS"
|
||||
format="HH:mm:ss:SS"
|
||||
/>
|
||||
```
|
||||
|
||||
@ -114,10 +114,22 @@ export default {
|
||||
| Attribute | Description | Type | Default | Version |
|
||||
|------|------|------|------|------|
|
||||
| time | Total time | *number* | - | - |
|
||||
| format | Time format,DD-day,HH-hour,mm-minute,ss-second,SSS-millisecond | *string* | `HH:mm:ss` | - |
|
||||
| format | Time format | *string* | `HH:mm:ss` | - |
|
||||
| auto-start | Whether to auto start count down | *boolean* | `true` | - |
|
||||
| millisecond | Whether to enable millisecond render | *boolean* | `false` | - |
|
||||
|
||||
### Available formats
|
||||
|
||||
| Format | Description |
|
||||
|------|------|
|
||||
| DD | Day |
|
||||
| HH | Hour |
|
||||
| mm | Minute |
|
||||
| ss | Second |
|
||||
| S | Millisecond, 1-digit |
|
||||
| SS | Millisecond, 2-digits |
|
||||
| SSS | Millisecond, 3-digits |
|
||||
|
||||
### Events
|
||||
|
||||
| Event | Description | Arguments |
|
||||
|
@ -48,7 +48,7 @@ export default {
|
||||
<van-count-down
|
||||
millisecond
|
||||
:time="time"
|
||||
format="HH:mm:ss:SSS"
|
||||
format="HH:mm:ss:SS"
|
||||
/>
|
||||
```
|
||||
|
||||
@ -124,10 +124,22 @@ export default {
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
|------|------|------|------|------|
|
||||
| time | 倒计时时长,单位毫秒 | *number* | - | - |
|
||||
| format | 时间格式,DD-日,HH-时,mm-分,ss-秒,SSS-毫秒 | *string* | `HH:mm:ss` | - |
|
||||
| format | 时间格式 | *string* | `HH:mm:ss` | - |
|
||||
| auto-start | 是否自动开始倒计时 | *boolean* | `true` | - |
|
||||
| millisecond | 是否开启毫秒级渲染 | *boolean* | `false` | - |
|
||||
|
||||
### format 格式
|
||||
|
||||
| 格式 | 说明 |
|
||||
|------|------|
|
||||
| DD | 天数 |
|
||||
| HH | 小时 |
|
||||
| mm | 分钟 |
|
||||
| ss | 秒数 |
|
||||
| S | 毫秒(1 位) |
|
||||
| SS | 毫秒(2 位) |
|
||||
| SSS | 毫秒(3 位) |
|
||||
|
||||
### Events
|
||||
|
||||
| 事件名 | 说明 | 回调参数 |
|
||||
|
@ -15,7 +15,7 @@
|
||||
<van-count-down
|
||||
millisecond
|
||||
:time="time"
|
||||
format="HH:mm:ss:SSS"
|
||||
format="HH:mm:ss:SS"
|
||||
/>
|
||||
</demo-block>
|
||||
|
||||
|
@ -5,3 +5,7 @@ exports[`complete format prop 1`] = `<div class="van-count-down">01-05-59-59-999
|
||||
exports[`disable auto-start prop 1`] = `<div class="van-count-down">100</div>`;
|
||||
|
||||
exports[`incomplate format prop 1`] = `<div class="van-count-down">29-59-59-999</div>`;
|
||||
|
||||
exports[`milliseconds format S 1`] = `<div class="van-count-down">01-5</div>`;
|
||||
|
||||
exports[`milliseconds format SS 1`] = `<div class="van-count-down">01-50</div>`;
|
||||
|
@ -141,6 +141,30 @@ test('complete format prop', () => {
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('milliseconds format SS', () => {
|
||||
const wrapper = mount(CountDown, {
|
||||
propsData: {
|
||||
time: 1500,
|
||||
autoStart: false,
|
||||
format: 'ss-SS'
|
||||
}
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('milliseconds format S', () => {
|
||||
const wrapper = mount(CountDown, {
|
||||
propsData: {
|
||||
time: 1500,
|
||||
autoStart: false,
|
||||
format: 'ss-S'
|
||||
}
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('incomplate format prop', () => {
|
||||
const wrapper = mount(CountDown, {
|
||||
propsData: {
|
||||
|
@ -57,7 +57,19 @@ export function parseFormat(format: string, timeData: TimeData): string {
|
||||
format = format.replace('ss', padZero(seconds));
|
||||
}
|
||||
|
||||
return format.replace('SSS', padZero(milliseconds, 3));
|
||||
if (format.indexOf('S') !== -1) {
|
||||
const ms = padZero(milliseconds, 3);
|
||||
|
||||
if (format.indexOf('SSS') !== -1) {
|
||||
format = format.replace('SSS', ms);
|
||||
} else if (format.indexOf('SS') !== -1) {
|
||||
format = format.replace('SS', ms.slice(0, 2));
|
||||
} else {
|
||||
format = format.replace('S', ms.charAt(0));
|
||||
}
|
||||
}
|
||||
|
||||
return format;
|
||||
}
|
||||
|
||||
export function isSameSecond(time1: number, time2: number): boolean {
|
||||
|
@ -89,7 +89,7 @@ declare global {
|
||||
}
|
||||
}
|
||||
|
||||
const version = '2.2.14';
|
||||
const version = '2.3.0-beta.1';
|
||||
const components = [
|
||||
ActionSheet,
|
||||
AddressEdit,
|
||||
|
@ -49,6 +49,10 @@ export default createComponent({
|
||||
};
|
||||
},
|
||||
|
||||
updated() {
|
||||
this.innerLoading = this.loading;
|
||||
},
|
||||
|
||||
mounted() {
|
||||
if (this.immediateCheck) {
|
||||
this.check();
|
||||
@ -56,11 +60,8 @@ export default createComponent({
|
||||
},
|
||||
|
||||
watch: {
|
||||
finished: 'check',
|
||||
loading(val) {
|
||||
this.innerLoading = val;
|
||||
this.check();
|
||||
}
|
||||
loading: 'check',
|
||||
finished: 'check'
|
||||
},
|
||||
|
||||
methods: {
|
||||
@ -112,7 +113,7 @@ export default createComponent({
|
||||
},
|
||||
|
||||
genLoading() {
|
||||
if (this.innerLoading) {
|
||||
if (this.innerLoading && !this.finished) {
|
||||
return (
|
||||
<div class={bem('loading')} key="loading">
|
||||
{this.slots('loading') || (
|
||||
|
@ -141,6 +141,7 @@ export default {
|
||||
| message-config | Message related config | *object* | `{}` | - |
|
||||
| get-container | Return the mount node for sku | *string \| () => Element* | - | - |
|
||||
| safe-area-inset-bottom | Whether to enable bottom safe area adaptation | *boolean* | `false` | 2.2.1 |
|
||||
| start-sale-num | Minimum quantity | *number* | `1` | 2.2.15 |
|
||||
|
||||
### Events
|
||||
|
||||
@ -258,10 +259,10 @@ customStepperConfig: {
|
||||
quotaText: 'only 5 can buy',
|
||||
// custom callback when over limit
|
||||
handleOverLimit: (data) => {
|
||||
const { action, limitType, quota, quotaUsed } = data;
|
||||
const { action, limitType, quota, quotaUsed, startSaleNum } = data;
|
||||
|
||||
if (action === 'minus') {
|
||||
Toast('at least select one');
|
||||
Toast(`at least select ${startSaleNum > 1 ? startSaleNum : 'one'}`);
|
||||
} else if (action === 'plus') {
|
||||
// const { LIMIT_TYPE } = Sku.skuConstants;
|
||||
if (limitType === LIMIT_TYPE.QUOTA_LIMIT) {
|
||||
|
@ -145,6 +145,7 @@ export default {
|
||||
| initial-sku | 默认选中的 sku,具体参考高级用法 | *object* | `{}` | - |
|
||||
| show-soldout-sku | 是否展示售罄的 sku,默认展示并置灰 | *boolean* | `true` | - |
|
||||
| safe-area-inset-bottom | 是否开启底部安全区适配,[详细说明](#/zh-CN/quickstart#di-bu-an-quan-qu-gua-pei) | *boolean* | `false` | 2.2.1 |
|
||||
| start-sale-num | 起售数量 | *number* | `1` | 2.2.15 |
|
||||
|
||||
### Events
|
||||
|
||||
@ -270,10 +271,10 @@ customStepperConfig: {
|
||||
quotaText: '每次限购xxx件',
|
||||
// 自定义步进器超过限制时的回调
|
||||
handleOverLimit: (data) => {
|
||||
const { action, limitType, quota, quotaUsed } = data;
|
||||
const { action, limitType, quota, quotaUsed, startSaleNum } = data;
|
||||
|
||||
if (action === 'minus') {
|
||||
Toast('至少选择一件商品');
|
||||
Toast(startSaleNum > 1 ? `${startSaleNum}件起售` : '至少选择一件商品');
|
||||
} else if (action === 'plus') {
|
||||
// const { LIMIT_TYPE } = Sku.skuConstants;
|
||||
if (limitType === LIMIT_TYPE.QUOTA_LIMIT) {
|
||||
|
@ -45,6 +45,10 @@ export default createComponent({
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
startSaleNum: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
initialSku: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
@ -236,22 +240,6 @@ export default createComponent({
|
||||
];
|
||||
},
|
||||
|
||||
quotaText() {
|
||||
const { quotaText, hideQuotaText } = this.customStepperConfig;
|
||||
|
||||
if (hideQuotaText) return '';
|
||||
|
||||
let text = '';
|
||||
|
||||
if (quotaText) {
|
||||
text = quotaText;
|
||||
} else if (this.quota > 0) {
|
||||
text = t('quotaLimit', this.quota);
|
||||
}
|
||||
|
||||
return text;
|
||||
},
|
||||
|
||||
selectedText() {
|
||||
if (this.selectedSkuComb) {
|
||||
return `${t('selected')} ${this.selectedSkuValues.map(item => item.name).join(';')}`;
|
||||
@ -274,6 +262,7 @@ export default createComponent({
|
||||
skuEventBus.$on('sku:numChange', this.onNumChange);
|
||||
skuEventBus.$on('sku:previewImage', this.onPreviewImage);
|
||||
skuEventBus.$on('sku:overLimit', this.onOverLimit);
|
||||
skuEventBus.$on('sku:stepperState', this.onStepperState);
|
||||
skuEventBus.$on('sku:addCart', this.onAddCart);
|
||||
skuEventBus.$on('sku:buy', this.onBuy);
|
||||
|
||||
@ -289,6 +278,8 @@ export default createComponent({
|
||||
const { skuStepper } = this.$refs;
|
||||
const { selectedNum } = this.initialSku;
|
||||
const num = isDef(selectedNum) ? selectedNum : 1;
|
||||
// 用来缓存不合法的情况
|
||||
this.stepperError = null;
|
||||
|
||||
if (skuStepper) {
|
||||
skuStepper.setCurrentNum(num);
|
||||
@ -409,18 +400,35 @@ export default createComponent({
|
||||
}
|
||||
|
||||
if (action === 'minus') {
|
||||
Toast(t('minusTip'));
|
||||
if (this.startSaleNum > 1) {
|
||||
Toast(t('minusStartTip', this.startSaleNum));
|
||||
} else {
|
||||
Toast(t('minusTip'));
|
||||
}
|
||||
} else if (action === 'plus') {
|
||||
if (limitType === QUOTA_LIMIT) {
|
||||
let msg = t('quotaLimit', quota);
|
||||
if (quotaUsed > 0) msg += `,${t('quotaCount', quotaUsed)}`;
|
||||
Toast(msg);
|
||||
if (quotaUsed > 0) {
|
||||
Toast(t('quotaUsedTip', quota, quotaUsed));
|
||||
} else {
|
||||
Toast(t('quotaTip', quota));
|
||||
}
|
||||
} else {
|
||||
Toast(t('soldout'));
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onStepperState(data) {
|
||||
if (data.valid) {
|
||||
this.stepperError = null;
|
||||
} else {
|
||||
this.stepperError = {
|
||||
...data,
|
||||
action: 'plus',
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
onAddCart() {
|
||||
this.onBuyOrAddCart('add-cart');
|
||||
},
|
||||
@ -430,6 +438,10 @@ export default createComponent({
|
||||
},
|
||||
|
||||
onBuyOrAddCart(type) {
|
||||
// 有信息表示该sku根本不符合购买条件
|
||||
if (this.stepperError) {
|
||||
return this.onOverLimit(this.stepperError);
|
||||
}
|
||||
const error = this.validateSku();
|
||||
if (error) {
|
||||
Toast(error);
|
||||
@ -463,7 +475,6 @@ export default createComponent({
|
||||
selectedSku,
|
||||
selectedNum,
|
||||
stepperTitle,
|
||||
hideQuotaText,
|
||||
selectedSkuComb
|
||||
} = this;
|
||||
|
||||
@ -494,7 +505,6 @@ export default createComponent({
|
||||
{!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 && (
|
||||
@ -530,6 +540,7 @@ export default createComponent({
|
||||
stock={this.stock}
|
||||
quota={this.quota}
|
||||
quotaUsed={this.quotaUsed}
|
||||
startSaleNum={this.startSaleNum}
|
||||
skuEventBus={skuEventBus}
|
||||
selectedNum={selectedNum}
|
||||
selectedSku={selectedSku}
|
||||
@ -537,6 +548,7 @@ export default createComponent({
|
||||
skuStockNum={sku.stock_num}
|
||||
disableStepperInput={this.disableStepperInput}
|
||||
customStepperConfig={this.customStepperConfig}
|
||||
hideQuotaText={this.hideQuotaText}
|
||||
onChange={event => {
|
||||
this.$emit('stepper-change', event);
|
||||
}}
|
||||
|
@ -16,6 +16,7 @@ export default createComponent({
|
||||
stepperTitle: String,
|
||||
disableStepperInput: Boolean,
|
||||
customStepperConfig: Object,
|
||||
hideQuotaText: Boolean,
|
||||
quota: {
|
||||
type: Number,
|
||||
default: 0
|
||||
@ -23,7 +24,11 @@ export default createComponent({
|
||||
quotaUsed: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
startSaleNum: {
|
||||
type: Number,
|
||||
default: 1,
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
@ -40,9 +45,17 @@ export default createComponent({
|
||||
},
|
||||
|
||||
stepperLimit(limit) {
|
||||
if (limit < this.currentNum) {
|
||||
if (limit < this.currentNum && this.stepperMinLimit <= limit) {
|
||||
this.currentNum = limit;
|
||||
}
|
||||
this.checkState(this.stepperMinLimit, limit);
|
||||
},
|
||||
|
||||
stepperMinLimit(start) {
|
||||
if (start > this.currentNum || start > this.stepperLimit) {
|
||||
this.currentNum = start;
|
||||
}
|
||||
this.checkState(start, this.stepperLimit);
|
||||
}
|
||||
},
|
||||
|
||||
@ -62,7 +75,35 @@ export default createComponent({
|
||||
}
|
||||
|
||||
return limit;
|
||||
}
|
||||
},
|
||||
stepperMinLimit() {
|
||||
return this.startSaleNum < 1 ? 1 : this.startSaleNum;
|
||||
},
|
||||
quotaText() {
|
||||
const { quotaText, hideQuotaText } = this.customStepperConfig;
|
||||
if (hideQuotaText) return '';
|
||||
|
||||
let text = '';
|
||||
|
||||
if (quotaText) {
|
||||
text = quotaText;
|
||||
} else {
|
||||
const textArr = [];
|
||||
if (this.startSaleNum > 1) {
|
||||
textArr.push(t('quotaStart', this.startSaleNum));
|
||||
}
|
||||
if (this.quota > 0) {
|
||||
textArr.push(t('quotaLimit', this.quota));
|
||||
}
|
||||
text = textArr.join(t('comma'));
|
||||
}
|
||||
|
||||
return text;
|
||||
},
|
||||
},
|
||||
|
||||
created() {
|
||||
this.checkState(this.stepperMinLimit, this.stepperLimit);
|
||||
},
|
||||
|
||||
methods: {
|
||||
@ -75,7 +116,8 @@ export default createComponent({
|
||||
action,
|
||||
limitType: this.limitType,
|
||||
quota: this.quota,
|
||||
quotaUsed: this.quotaUsed
|
||||
quotaUsed: this.quotaUsed,
|
||||
startSaleNum: this.startSaleNum,
|
||||
});
|
||||
},
|
||||
|
||||
@ -83,7 +125,27 @@ export default createComponent({
|
||||
const { handleStepperChange } = this.customStepperConfig;
|
||||
handleStepperChange && handleStepperChange(currentValue);
|
||||
this.$emit('change', currentValue);
|
||||
}
|
||||
},
|
||||
|
||||
checkState(min, max) {
|
||||
// 如果选择小于起售,则强制变为起售
|
||||
if (this.currentNum < min || min > max) {
|
||||
this.currentNum = min;
|
||||
} else if (this.currentNum > max) {
|
||||
// 当前选择数量大于最大可选时,需要重置已选数量
|
||||
this.currentNum = max;
|
||||
}
|
||||
|
||||
this.skuEventBus.$emit('sku:stepperState', {
|
||||
valid: min <= max,
|
||||
min,
|
||||
max,
|
||||
limitType: this.limitType,
|
||||
quota: this.quota,
|
||||
quotaUsed: this.quotaUsed,
|
||||
startSaleNum: this.startSaleNum,
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
render() {
|
||||
@ -94,11 +156,13 @@ export default createComponent({
|
||||
<Stepper
|
||||
vModel={this.currentNum}
|
||||
class="van-sku__stepper"
|
||||
min={this.stepperMinLimit}
|
||||
max={this.stepperLimit}
|
||||
disableInput={this.disableStepperInput}
|
||||
onOverlimit={this.onOverLimit}
|
||||
onChange={this.onChange}
|
||||
/>
|
||||
{!this.hideQuotaText && this.quotaText && <span class="van-sku__stepper-quota">({this.quotaText})</span>}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -2,6 +2,7 @@ export default {
|
||||
goods_id: '946755',
|
||||
quota: 15,
|
||||
quota_used: 0,
|
||||
start_sale_num: 10,
|
||||
goods_info: {
|
||||
title: '测试商品',
|
||||
picture:
|
||||
|
@ -11,6 +11,7 @@
|
||||
: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"
|
||||
@ -42,6 +43,7 @@
|
||||
:hide-stock="skuData.sku.hide_stock"
|
||||
:quota="skuData.quota"
|
||||
:quota-used="skuData.quota_used"
|
||||
:start-sale-num="skuData.start_sale_num"
|
||||
:custom-stepper-config="customStepperConfig"
|
||||
:message-config="messageConfig"
|
||||
hide-quota-text
|
||||
@ -70,6 +72,7 @@
|
||||
:hide-stock="skuData.sku.hide_stock"
|
||||
:quota="skuData.quota"
|
||||
:quota-used="skuData.quota_used"
|
||||
:start-sale-num="skuData.start_sale_num"
|
||||
:custom-stepper-config="customStepperConfig"
|
||||
:message-config="messageConfig"
|
||||
:show-soldout-sku="false"
|
||||
@ -99,6 +102,7 @@
|
||||
:hide-stock="skuData.sku.hide_stock"
|
||||
:quota="skuData.quota"
|
||||
:quota-used="skuData.quota_used"
|
||||
:start-sale-num="skuData.start_sale_num"
|
||||
show-add-cart-btn
|
||||
reset-stepper-on-hide
|
||||
safe-area-inset-bottom
|
||||
@ -126,7 +130,7 @@
|
||||
square
|
||||
size="large"
|
||||
type="danger"
|
||||
@click="props.skuEventBus.$emit('sku:buy')"
|
||||
@click="skuEventBus.$emit('sku:buy')"
|
||||
>
|
||||
{{ $t('button2') }}
|
||||
</van-button>
|
||||
@ -185,10 +189,10 @@ export default {
|
||||
quotaText: '单次限购100件',
|
||||
stockFormatter: (stock) => `剩余${stock}件`,
|
||||
handleOverLimit: (data) => {
|
||||
const { action, limitType, quota } = data;
|
||||
const { action, limitType, quota, startSaleNum = 1 } = data;
|
||||
|
||||
if (action === 'minus') {
|
||||
this.$toast('至少选择一件商品');
|
||||
this.$toast(startSaleNum > 1 ? `${startSaleNum}件起售` : '至少选择一件商品');
|
||||
} else if (action === 'plus') {
|
||||
if (limitType === LIMIT_TYPE.QUOTA_LIMIT) {
|
||||
this.$toast(`限购${quota}件`);
|
||||
|
@ -196,18 +196,28 @@
|
||||
}
|
||||
|
||||
&-container {
|
||||
height: 30px;
|
||||
min-height: 30px;
|
||||
margin-right: 20px;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
&__stepper {
|
||||
float: right;
|
||||
padding-left: @padding-base;
|
||||
|
||||
&-title {
|
||||
float: left;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
&-quota {
|
||||
display: inline-block;
|
||||
float: right;
|
||||
color: @red;
|
||||
font-size: @font-size-sm;
|
||||
line-height: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
&__stock {
|
||||
@ -221,12 +231,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
&__quota {
|
||||
display: inline-block;
|
||||
color: @red;
|
||||
font-size: @font-size-sm;
|
||||
}
|
||||
|
||||
&-messages {
|
||||
padding-bottom: @padding-xl;
|
||||
|
||||
|
@ -11,11 +11,12 @@ export default {
|
||||
soldout: '库存不足',
|
||||
originPrice: '原价',
|
||||
minusTip: '至少选择一件',
|
||||
minusStartTip: (start: number) => `${start}件起售`,
|
||||
unavailable: '商品已经无法购买啦',
|
||||
stock: '剩余',
|
||||
stockUnit: '件',
|
||||
quotaLimit: (quota: number) => `每人限购${quota}件`,
|
||||
quotaCount: (count: number) => `你已购买${count}件`
|
||||
quotaTip: (quota: number) => `每人限购${quota}件`,
|
||||
quotaUsedTip: (quota: number, count: number) => `每人限购${quota}件,你已购买${count}件`
|
||||
},
|
||||
vanSkuActions: {
|
||||
buy: '立即购买',
|
||||
@ -26,6 +27,9 @@ export default {
|
||||
fail: '上传失败<br />重新上传'
|
||||
},
|
||||
vanSkuStepper: {
|
||||
quotaLimit: (quota: number) => `限购${quota}件`,
|
||||
quotaStart: (start: number) => `${start}件起售`,
|
||||
comma: ',',
|
||||
num: '购买数量'
|
||||
},
|
||||
vanSkuMessages: {
|
||||
|
@ -42,6 +42,7 @@
|
||||
@font-size-md: 14px;
|
||||
@font-size-lg: 16px;
|
||||
@font-weight-bold: 500;
|
||||
@price-integer-font-family: Avenir-Heavy PingFang SC, Helvetica Neue, Arial, sans-serif;
|
||||
|
||||
// Animation
|
||||
@animation-duration-base: .3s;
|
||||
@ -52,6 +53,7 @@
|
||||
@border-width-base: 1px;
|
||||
@border-radius-sm: 2px;
|
||||
@border-radius-md: 4px;
|
||||
@border-radius-lg: 8px;
|
||||
@border-radius-max: 999px;
|
||||
|
||||
// ActionSheet
|
||||
@ -137,13 +139,17 @@
|
||||
@card-font-size: @font-size-sm;
|
||||
@card-text-color: @text-color;
|
||||
@card-background-color: @background-color-light;
|
||||
@card-thumb-size: 90px;
|
||||
@card-thumb-size: 88px;
|
||||
@card-thumb-border-radius: @border-radius-lg;
|
||||
@card-title-line-height: 16px;
|
||||
@card-desc-color: @gray-7;
|
||||
@card-desc-line-height: 20px;
|
||||
@card-price-color: @red;
|
||||
@card-origin-price-color: @gray-7;
|
||||
@card-price-color: @gray-8;
|
||||
@card-origin-price-color: @gray-6;
|
||||
@card-num-color: @gray-6;
|
||||
@card-origin-price-font-size: @font-size-xs;
|
||||
@card-price-integer-font-size: @font-size-lg;
|
||||
@card-price-font-family: @price-integer-font-family;
|
||||
|
||||
// Cell
|
||||
@cell-font-size: @font-size-md;
|
||||
@ -596,7 +602,7 @@
|
||||
@submit-bar-background-color: @white;
|
||||
@submit-bar-button-width: 110px;
|
||||
@submit-bar-price-color: @red;
|
||||
@submit-bar-price-font-size: 18px;
|
||||
@submit-bar-price-font-size: @font-size-md;
|
||||
@submit-bar-currency-font-size: @font-size-md;
|
||||
@submit-bar-text-color: @text-color;
|
||||
@submit-bar-text-font-size: @font-size-md;
|
||||
@ -606,6 +612,10 @@
|
||||
@submit-bar-tip-color: #f56723;
|
||||
@submit-bar-tip-background-color: #fff7cc;
|
||||
@submit-bar-tip-icon-size: 12px;
|
||||
@submit-bar-button-height: 40px;
|
||||
@submit-bar-padding: 0 @padding-md;
|
||||
@submit-bar-price-integer-font-size: 20px;
|
||||
@submit-bar-price-font-family: @price-integer-font-family;
|
||||
|
||||
// Swipe
|
||||
@swipe-indicator-size: 6px;
|
||||
@ -669,7 +679,7 @@
|
||||
@tag-text-color: @white;
|
||||
@tag-border-radius: .2em;
|
||||
@tag-round-border-radius: @border-radius-max;
|
||||
@tag-dander-color: @red;
|
||||
@tag-danger-color: @red;
|
||||
@tag-primary-color: @blue;
|
||||
@tag-success-color: @green;
|
||||
@tag-warning-color: @orange;
|
||||
@ -683,7 +693,7 @@
|
||||
@toast-loading-icon-color: @white;
|
||||
@toast-line-height: 20px;
|
||||
@toast-border-radius: @border-radius-md;
|
||||
@toast-background-color: rgba(@text-color, .88);
|
||||
@toast-background-color: fade(@text-color, 88%);
|
||||
@toast-icon-size: 40px;
|
||||
@toast-text-min-width: 96px;
|
||||
@toast-text-padding: @padding-xs @padding-sm;
|
||||
|
@ -75,6 +75,7 @@ Use slot to add custom contents.
|
||||
| price | Price | *number* | - | - |
|
||||
| label | Price left label | *string* | `Total:` | - |
|
||||
| suffix-label | Price right label | *string* | - | - |
|
||||
| text-align | Price label text align can be set to `right` `left` | *string* | `right` | - |
|
||||
| button-text | Button text | *string* | - | - |
|
||||
| button-type | Button type | *string* | `danger` | - |
|
||||
| tip | Tip | *string* | - | - |
|
||||
|
@ -75,6 +75,7 @@ Vue.use(SubmitBar);
|
||||
| price | 价格(单位分) | *number* | - | - |
|
||||
| label | 价格左侧文案 | *string* | `合计:` | - |
|
||||
| suffix-label | 价格右侧文案 | *string* | - | - |
|
||||
| text-align | 价格文案对齐方向,可选值为 `right` `left` | *string* | `right` | - |
|
||||
| button-text | 按钮文字 | *string* | - | - |
|
||||
| button-type | 按钮类型 | *string* | `danger` | - |
|
||||
| tip | 提示文案 | *string* | - | - |
|
||||
@ -82,7 +83,7 @@ Vue.use(SubmitBar);
|
||||
| disabled | 是否禁用按钮 | *boolean* | `false` | - |
|
||||
| loading | 是否显示加载中的按钮 | *boolean* | `false` | - |
|
||||
| currency | 货币符号 | *string* | `¥` | - |
|
||||
| decimal-length | 价格小数点后位数 | *number* | `2` | - |
|
||||
| decimal-length | 价格小数点后位数 | *number* | `2` | - |
|
||||
| safe-area-inset-bottom | 是否开启底部安全区适配,[详细说明](#/zh-CN/quickstart#di-bu-an-quan-qu-gua-pei) | *boolean* | `false` | - |
|
||||
|
||||
### Events
|
||||
|
@ -102,7 +102,7 @@ export default {
|
||||
}
|
||||
|
||||
.van-checkbox {
|
||||
margin-left: @padding-sm;
|
||||
margin-right: @padding-sm;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -32,6 +32,7 @@
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
height: @submit-bar-height;
|
||||
padding: @submit-bar-padding;
|
||||
font-size: @submit-bar-text-font-size;
|
||||
}
|
||||
|
||||
@ -39,7 +40,6 @@
|
||||
flex: 1;
|
||||
padding-right: @padding-sm;
|
||||
color: @submit-bar-text-color;
|
||||
font-weight: @font-weight-bold;
|
||||
text-align: right;
|
||||
|
||||
span {
|
||||
@ -49,19 +49,30 @@
|
||||
|
||||
&__suffix-label {
|
||||
margin-left: 5px;
|
||||
font-weight: @font-weight-bold;
|
||||
}
|
||||
|
||||
&__price {
|
||||
color: @submit-bar-price-color;
|
||||
font-size: @submit-bar-price-font-size;
|
||||
font-weight: @font-weight-bold;
|
||||
font-size: @font-size-sm;
|
||||
|
||||
&::first-letter {
|
||||
font-size: @submit-bar-currency-font-size;
|
||||
&--integer {
|
||||
font-size: @submit-bar-price-integer-font-size;
|
||||
font-family: @submit-bar-price-font-family;
|
||||
}
|
||||
}
|
||||
|
||||
&__button {
|
||||
width: @submit-bar-button-width;
|
||||
height: @submit-bar-button-height;
|
||||
font-weight: @font-weight-bold;
|
||||
line-height: @submit-bar-button-height;
|
||||
border: none;
|
||||
|
||||
&--danger {
|
||||
background: @goods-action-button-danger-color;
|
||||
}
|
||||
}
|
||||
|
||||
&--safe-area-inset-bottom {
|
||||
|
@ -20,6 +20,7 @@ export type SubmitBarProps = {
|
||||
suffixLabel?: string;
|
||||
decimalLength: number;
|
||||
safeAreaInsetBottom?: boolean;
|
||||
textAlign?: 'right' | 'left';
|
||||
};
|
||||
|
||||
export type SubmitBarSlots = DefaultSlots & {
|
||||
@ -39,12 +40,14 @@ function SubmitBar(
|
||||
|
||||
function Text() {
|
||||
if (typeof price === 'number') {
|
||||
const priceText = `${props.currency} ${(price / 100).toFixed(props.decimalLength)}`;
|
||||
|
||||
const priceArr = (price / 100).toFixed(props.decimalLength).split('.');
|
||||
return (
|
||||
<div class={bem('text')}>
|
||||
<div style={{ textAlign: props.textAlign ? props.textAlign : '' }} class={bem('text')}>
|
||||
<span>{props.label || t('label')}</span>
|
||||
<span class={bem('price')}>{priceText}</span>
|
||||
<span class={bem('price')}>
|
||||
{props.currency}
|
||||
<span class={bem('price', 'integer')}>{priceArr[0]}</span>.{priceArr[1]}
|
||||
</span>
|
||||
{props.suffixLabel && (
|
||||
<span class={bem('suffix-label')}>{props.suffixLabel}</span>
|
||||
)}
|
||||
@ -76,9 +79,8 @@ function SubmitBar(
|
||||
{slots.default && slots.default()}
|
||||
{Text()}
|
||||
<Button
|
||||
square
|
||||
size="large"
|
||||
class={bem('button')}
|
||||
round
|
||||
class={bem('button', props.buttonType)}
|
||||
type={props.buttonType}
|
||||
loading={props.loading}
|
||||
disabled={props.disabled}
|
||||
@ -113,7 +115,8 @@ SubmitBar.props = {
|
||||
buttonType: {
|
||||
type: String,
|
||||
default: 'danger'
|
||||
}
|
||||
},
|
||||
textAlign: String,
|
||||
};
|
||||
|
||||
export default createComponent<SubmitBarProps, {}, SubmitBarSlots>(SubmitBar);
|
||||
|
@ -5,7 +5,7 @@ exports[`renders demo correctly 1`] = `
|
||||
<div>
|
||||
<div class="van-submit-bar">
|
||||
<div class="van-submit-bar__bar">
|
||||
<div class="van-submit-bar__text"><span>合计:</span><span class="van-submit-bar__price">¥ 30.50</span></div><button class="van-button van-button--danger van-button--large van-button--square van-submit-bar__button"><span class="van-button__text">提交订单</span></button>
|
||||
<div class="van-submit-bar__text"><span>合计:</span><span class="van-submit-bar__price">¥<span class="van-submit-bar__price van-submit-bar__price--integer">30</span>.50</span></div><button class="van-button van-button--danger van-button--normal van-button--round van-submit-bar__button van-submit-bar__button--danger"><span class="van-button__text">提交订单</span></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -14,14 +14,14 @@ exports[`renders demo correctly 1`] = `
|
||||
<div class="van-submit-bar__tip"><i class="van-icon van-icon-info-o van-submit-bar__tip-icon">
|
||||
<!----></i><span class="van-submit-bar__tip-text">你的收货地址不支持同城送, 我们已为你推荐快递</span></div>
|
||||
<div class="van-submit-bar__bar">
|
||||
<div class="van-submit-bar__text"><span>合计:</span><span class="van-submit-bar__price">¥ 30.50</span></div><button disabled="disabled" class="van-button van-button--danger van-button--large van-button--disabled van-button--square van-submit-bar__button"><span class="van-button__text">提交订单</span></button>
|
||||
<div class="van-submit-bar__text"><span>合计:</span><span class="van-submit-bar__price">¥<span class="van-submit-bar__price van-submit-bar__price--integer">30</span>.50</span></div><button disabled="disabled" class="van-button van-button--danger van-button--normal van-button--disabled van-button--round van-submit-bar__button van-submit-bar__button--danger"><span class="van-button__text">提交订单</span></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="van-submit-bar">
|
||||
<div class="van-submit-bar__bar">
|
||||
<div class="van-submit-bar__text"><span>合计:</span><span class="van-submit-bar__price">¥ 30.50</span></div><button class="van-button van-button--danger van-button--large van-button--square van-submit-bar__button">
|
||||
<div class="van-submit-bar__text"><span>合计:</span><span class="van-submit-bar__price">¥<span class="van-submit-bar__price van-submit-bar__price--integer">30</span>.50</span></div><button class="van-button van-button--danger van-button--normal van-button--round van-submit-bar__button van-submit-bar__button--danger">
|
||||
<div class="van-loading van-loading--circular van-button__loading"><span class="van-loading__spinner van-loading__spinner--circular" style="color: currentColor; width: 20px; height: 20px;"><svg viewBox="25 25 50 50" class="van-loading__circular"><circle cx="50" cy="50" r="20" fill="none"></circle></svg></span></div>
|
||||
</button>
|
||||
</div>
|
||||
@ -39,7 +39,7 @@ exports[`renders demo correctly 1`] = `
|
||||
<div class="van-checkbox__icon van-checkbox__icon--round van-checkbox__icon--checked"><i class="van-icon van-icon-success">
|
||||
<!----></i></div><span class="van-checkbox__label">全选</span>
|
||||
</div>
|
||||
<div class="van-submit-bar__text"><span>合计:</span><span class="van-submit-bar__price">¥ 30.50</span></div><button class="van-button van-button--danger van-button--large van-button--square van-submit-bar__button"><span class="van-button__text">提交订单</span></button>
|
||||
<div class="van-submit-bar__text"><span>合计:</span><span class="van-submit-bar__price">¥<span class="van-submit-bar__price van-submit-bar__price--integer">30</span>.50</span></div><button class="van-button van-button--danger van-button--normal van-button--round van-submit-bar__button van-submit-bar__button--danger"><span class="van-button__text">提交订单</span></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -3,7 +3,7 @@
|
||||
exports[`decimal-length prop 1`] = `
|
||||
<div class="van-submit-bar">
|
||||
<div class="van-submit-bar__bar">
|
||||
<div class="van-submit-bar__text"><span>合计:</span><span class="van-submit-bar__price">¥ 1.1</span></div><button class="van-button van-button--danger van-button--large van-button--square van-submit-bar__button"></button>
|
||||
<div class="van-submit-bar__text"><span>合计:</span><span class="van-submit-bar__price">¥<span class="van-submit-bar__price van-submit-bar__price--integer">1</span>.1</span></div><button class="van-button van-button--danger van-button--normal van-button--round van-submit-bar__button van-submit-bar__button--danger"></button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@ -11,7 +11,7 @@ exports[`decimal-length prop 1`] = `
|
||||
exports[`disable submit 1`] = `
|
||||
<div class="van-submit-bar">
|
||||
<div class="van-submit-bar__bar">
|
||||
<div class="van-submit-bar__text"><span>合计:</span><span class="van-submit-bar__price">¥ 0.01</span></div><button disabled="disabled" class="van-button van-button--danger van-button--large van-button--disabled van-button--square van-submit-bar__button"></button>
|
||||
<div class="van-submit-bar__text"><span>合计:</span><span class="van-submit-bar__price">¥<span class="van-submit-bar__price van-submit-bar__price--integer">0</span>.01</span></div><button disabled="disabled" class="van-button van-button--danger van-button--normal van-button--disabled van-button--round van-submit-bar__button van-submit-bar__button--danger"></button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@ -19,18 +19,26 @@ exports[`disable submit 1`] = `
|
||||
exports[`suffix-label prop 1`] = `
|
||||
<div class="van-submit-bar">
|
||||
<div class="van-submit-bar__bar">
|
||||
<div class="van-submit-bar__text"><span>Label</span><span class="van-submit-bar__price">¥ 1.11</span><span class="van-submit-bar__suffix-label">Suffix Label</span></div><button class="van-button van-button--danger van-button--large van-button--square van-submit-bar__button"></button>
|
||||
<div class="van-submit-bar__text"><span>Label</span><span class="van-submit-bar__price">¥<span class="van-submit-bar__price van-submit-bar__price--integer">1</span>.11</span><span class="van-submit-bar__suffix-label">Suffix Label</span></div><button class="van-button van-button--danger van-button--normal van-button--round van-submit-bar__button van-submit-bar__button--danger"></button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`text-align prop 1`] = `
|
||||
<div class="van-submit-bar">
|
||||
<div class="van-submit-bar__bar">
|
||||
<div class="van-submit-bar__text" style="text-align: left;"><span>合计:</span><span class="van-submit-bar__price">¥<span class="van-submit-bar__price van-submit-bar__price--integer">1</span>.11</span></div><button class="van-button van-button--danger van-button--normal van-button--round van-submit-bar__button van-submit-bar__button--danger"></button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`top slot 1`] = `
|
||||
<div class="van-submit-bar">top<div class="van-submit-bar__bar"><button class="van-button van-button--danger van-button--large van-button--square van-submit-bar__button"></button></div>
|
||||
<div class="van-submit-bar">top<div class="van-submit-bar__bar"><button class="van-button van-button--danger van-button--normal van-button--round van-submit-bar__button van-submit-bar__button--danger"></button></div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`without price 1`] = `
|
||||
<div class="van-submit-bar">
|
||||
<div class="van-submit-bar__bar"><button class="van-button van-button--danger van-button--large van-button--square van-submit-bar__button"></button></div>
|
||||
<div class="van-submit-bar__bar"><button class="van-button van-button--danger van-button--normal van-button--round van-submit-bar__button van-submit-bar__button--danger"></button></div>
|
||||
</div>
|
||||
`;
|
||||
|
@ -85,3 +85,15 @@ test('suffix-label prop', () => {
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('text-align prop', () => {
|
||||
const wrapper = mount(SubmitBar, {
|
||||
context: {
|
||||
props: {
|
||||
price: 111,
|
||||
textAlign: 'left'
|
||||
}
|
||||
}
|
||||
});
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
@ -23,10 +23,10 @@
|
||||
}
|
||||
|
||||
&--danger {
|
||||
background-color: @tag-dander-color;
|
||||
background-color: @tag-danger-color;
|
||||
|
||||
&.van-tag--plain {
|
||||
color: @tag-dander-color;
|
||||
color: @tag-danger-color;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -97,9 +97,8 @@ function TreeSelect(
|
||||
}
|
||||
}
|
||||
|
||||
emit(ctx, 'click-item', item);
|
||||
emit(ctx, 'update:active-id', newActiveId);
|
||||
|
||||
emit(ctx, 'click-item', item);
|
||||
// compatible for old usage, should be removed in next major version
|
||||
emit(ctx, 'itemclick', item);
|
||||
}
|
||||
@ -119,9 +118,8 @@ function TreeSelect(
|
||||
class={bem('nav')}
|
||||
activeKey={mainActiveIndex}
|
||||
onChange={(index: number) => {
|
||||
emit(ctx, 'click-nav', index);
|
||||
emit(ctx, 'update:main-active-index', index);
|
||||
|
||||
emit(ctx, 'click-nav', index);
|
||||
// compatible for old usage, should be removed in next major version
|
||||
emit(ctx, 'navclick', index);
|
||||
}}
|
||||
|
@ -295,3 +295,37 @@ test('className of nav', () => {
|
||||
const items = wrapper.findAll('.van-tree-select__nav-item');
|
||||
expect(items.at(0).element.classList.contains('my-class')).toBeTruthy();
|
||||
});
|
||||
|
||||
test('should sync value before trigger click-item event', done => {
|
||||
const wrapper = mount({
|
||||
template: `
|
||||
<van-tree-select
|
||||
:items="items"
|
||||
:main-active-index="0"
|
||||
:active-id.sync="activeId"
|
||||
@click-item="onClickItem"
|
||||
/>
|
||||
`,
|
||||
data() {
|
||||
return {
|
||||
activeId: mockItem.id,
|
||||
mainActiveIndex: 0,
|
||||
items: [
|
||||
{
|
||||
text: 'group1',
|
||||
children: [mockItem, mockItem2]
|
||||
}
|
||||
]
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
onClickItem() {
|
||||
expect(wrapper.vm.activeId).toEqual(mockItem2.id);
|
||||
done();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const items = wrapper.findAll('.van-tree-select__item');
|
||||
items.at(1).trigger('click');
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user