add PayOrder component

This commit is contained in:
陈嘉涵 2017-08-29 15:59:19 +08:00
parent 67a3c16a62
commit 3a32c24573
7 changed files with 316 additions and 0 deletions

View File

@ -0,0 +1,87 @@
## PayOrder 支付订单
<script>
import { Toast } from 'packages/index';
export default {
methods: {
onClickButton() {
Toast('点击按钮');
}
}
}
</script>
<style>
.demo-pay-order {
.van-pay-order {
position: relative;
}
}
</style>
### 使用指南
``` javascript
import { PayOrder } from 'vant';
Vue.component(PayOrder.name, PayOrder);
```
### 代码演示
#### 基础用法
:::demo 基础用法
```html
<van-pay-order
:price="3050"
button-text="提交订单"
@submit="onClickButton"
/>
```
:::
#### 禁用状态
禁用状态下不会触发`submit`事件
:::demo 禁用状态
```html
<van-pay-order
disabled
:price="3050"
button-text="提交订单"
tip="您的收货地址不支持同城送, 我们已为您推荐快递"
@submit="onClickButton"
/>
```
:::
#### 加载状态
加载状态下不会触发`submit`事件
:::demo 加载状态
```html
<van-pay-order
loading
:price="3050"
button-text="提交订单"
@submit="onClickButton"
/>
```
:::
### API
| 参数 | 说明 | 类型 | 默认值 | 必须 |
|-----------|-----------|-----------|-------------|-------------|
| price | 价格(单位分) | `Number` | | 是 |
| button-text | 按钮文字 | `String` | | 是 |
| button-type | 按钮类型 | `String` | `danger` | 否 |
| tip | 提示文案 | `String` | | 否 |
| disabled | 是否禁用按钮 | `Boolean` | `false` | 否 |
| loading | 是否显示加载中的按钮 | `Boolean` | `false` | 否 |
### Event
| 事件名 | 说明 | 参数 |
|-----------|-----------|-----------|
| submit | 按钮点击事件回调 | - |

View File

@ -189,6 +189,10 @@ module.exports = {
"path": "/express-way",
"title": "ExpressWay 配送方式"
},
{
"path": "/pay-order",
"title": "PayOrder 提交订单栏"
},
{
"path": "/switch-cell",
"title": "SwitchCell 开关单元格"

View File

@ -19,6 +19,7 @@ import Lazyload from './lazyload';
import Loading from './loading';
import NoticeBar from './notice-bar';
import Panel from './panel';
import PayOrder from './pay-order';
import Picker from './picker';
import Popup from './popup';
import Progress from './progress';
@ -60,6 +61,7 @@ const components = [
Loading,
NoticeBar,
Panel,
PayOrder,
Picker,
Popup,
Progress,
@ -117,6 +119,7 @@ export {
Loading,
NoticeBar,
Panel,
PayOrder,
Picker,
Popup,
Progress,

View File

@ -0,0 +1,63 @@
<template>
<div class="van-pay-order">
<div class="van-pay-order__tip" v-show="tip">{{ tip }}</div>
<div class="van-pay-order__bar">
<div class="van-pay-order__price">
<span class="van-pay-order__price-text">合计</span>
<span class="van-pay-order__price-interger">¥{{ priceInterger }}.</span>
<span class="van-pay-order__price-decimal">{{ priceDecimal }}</span>
</div>
<van-button :type="buttonType" :disabled="disabled" :loading="loading" @click="onSubmit">
{{ loading ? '' : buttonText }}
</van-button>
</div>
</div>
</template>
<script>
import Button from '../button';
export default {
name: 'van-pay-order',
components: {
[Button.name]: Button
},
props: {
tip: String,
disabled: Boolean,
loading: Boolean,
buttonText: {
type: String,
required: true
},
buttonType: {
type: String,
default: 'danger'
},
price: {
type: Number,
required: true
}
},
computed: {
priceInterger() {
return Math.floor(this.price / 100);
},
priceDecimal() {
const decimal = this.price % 100;
return (decimal < 10 ? '0' : '') + decimal;
}
},
methods: {
onSubmit() {
if (!this.disabled && !this.loading) {
this.$emit('submit');
}
}
}
};
</script>

View File

@ -33,3 +33,4 @@
@import './notice-bar.css';
@import './switch-cell.css';
@import './express-way.css';
@import './pay-order.css';

View File

@ -0,0 +1,59 @@
.van-pay-order {
left: 0;
bottom: 0;
width: 100%;
z-index: 100;
position: fixed;
user-select: none;
&__tip {
color: #f60;
font-size: 12px;
line-height: 18px;
padding: 10px 10px;
background-color: #fff6e1;
}
&__bar {
height: 50px;
display: flex;
line-height: 50px;
background-color: #fff;
}
&__price {
flex: 1;
text-align: right;
padding-right: 10px;
}
&__price-text {
color: #666;
font-size: 16px;
}
&__price-interger {
color: #f44;
font-size: 16px;
}
&__price-decimal {
color: #f44;
font-size: 12px;
}
.van-button {
width: 110px;
height: 100%;
border-radius: 0;
&--disabled {
border: none;
}
.van-loading__spinner--white {
border-color: rgba(255,255,255, .8);
border-top-color: transparent;
}
}
}

View File

@ -0,0 +1,99 @@
import PayOrder from 'packages/pay-order';
import { mount } from 'avoriaz';
import { DOMChecker } from '../utils';
describe('PayOrder', () => {
let wrapper;
afterEach(() => {
wrapper && wrapper.destroy();
});
it('default', () => {
const props = {
price: 3050,
buttonText: '提交订单',
tip: '您的收货地址不支持同城送, 我们已为您推荐快递'
};
wrapper = mount(PayOrder, {
propsData: props
});
DOMChecker(wrapper, {
text: {
'.van-button__text': props.buttonText,
'.van-pay-order__price-interger': '¥30.',
'.van-pay-order__price-decimal': '50',
'.van-pay-order__tip': props.tip
}
});
});
it('no tip', () => {
wrapper = mount(PayOrder, {
propsData: {
price: 3005,
buttonText: '提交订单'
}
});
DOMChecker(wrapper, {
text: {
'.van-button__text': '提交订单',
'.van-pay-order__price-interger': '¥30.',
'.van-pay-order__price-decimal': '05',
'.van-pay-order__tip': ''
}
});
});
it('handle submit', () => {
wrapper = mount(PayOrder, {
propsData: {
price: 3005,
buttonText: '提交订单'
}
});
const submitSpyFunc = sinon.spy();
wrapper.vm.$on('submit', submitSpyFunc);
wrapper.find('.van-button')[0].trigger('click');
setTimeout(() => {
expect(submitSpyFunc.calledOnce).to.be.true;
}, 300);
});
it('can not submit when disabled', () => {
wrapper = mount(PayOrder, {
propsData: {
price: 3005,
disabled: true,
buttonText: '提交订单'
}
});
const submitSpyFunc = sinon.spy();
wrapper.vm.$on('submit', submitSpyFunc);
wrapper.find('.van-button')[0].trigger('click');
setTimeout(() => {
expect(submitSpyFunc.calledOnce).to.be.false;
}, 300);
});
it('can not submit when loading', () => {
wrapper = mount(PayOrder, {
propsData: {
price: 3005,
loading: true,
buttonText: '提交订单'
}
});
const submitSpyFunc = sinon.spy();
wrapper.vm.$on('submit', submitSpyFunc);
wrapper.find('.van-button')[0].trigger('click');
setTimeout(() => {
expect(submitSpyFunc.calledOnce).to.be.false;
}, 300);
});
});