diff --git a/build/webpack.config.dev.js b/build/webpack.config.dev.js index c7704eae6..f4657d327 100644 --- a/build/webpack.config.dev.js +++ b/build/webpack.config.dev.js @@ -60,6 +60,7 @@ module.exports = { { loader: 'vue-loader', options: { + preserveWhitespace: false, loaders: { postcss: ExtractTextPlugin.extract({ use: styleLoaders, diff --git a/docs/examples-docs/pay-order.md b/docs/examples-docs/pay-order.md new file mode 100644 index 000000000..1df37b4a2 --- /dev/null +++ b/docs/examples-docs/pay-order.md @@ -0,0 +1,87 @@ +## PayOrder 支付订单 + + + + + +### 使用指南 +``` javascript +import { PayOrder } from 'vant'; + +Vue.component(PayOrder.name, PayOrder); +``` + +### 代码演示 + +#### 基础用法 + +:::demo 基础用法 +```html + +``` +::: + +#### 禁用状态 +禁用状态下不会触发`submit`事件 + +:::demo 禁用状态 +```html + +``` +::: + +#### 加载状态 +加载状态下不会触发`submit`事件 +:::demo 加载状态 +```html + +``` +::: + +### API + +| 参数 | 说明 | 类型 | 默认值 | 必须 | +|-----------|-----------|-----------|-------------|-------------| +| price | 价格(单位分) | `Number` | | 是 | +| button-text | 按钮文字 | `String` | | 是 | +| button-type | 按钮类型 | `String` | `danger` | 否 | +| tip | 提示文案 | `String` | | 否 | +| disabled | 是否禁用按钮 | `Boolean` | `false` | 否 | +| loading | 是否显示加载中的按钮 | `Boolean` | `false` | 否 | + +### Event + +| 事件名 | 说明 | 参数 | +|-----------|-----------|-----------| +| submit | 按钮点击事件回调 | - | diff --git a/docs/src/doc.config.js b/docs/src/doc.config.js index 364ce26be..64da013eb 100644 --- a/docs/src/doc.config.js +++ b/docs/src/doc.config.js @@ -189,6 +189,10 @@ module.exports = { "path": "/express-way", "title": "ExpressWay 配送方式" }, + { + "path": "/pay-order", + "title": "PayOrder 提交订单栏" + }, { "path": "/switch-cell", "title": "SwitchCell 开关单元格" diff --git a/package.json b/package.json index b24c40444..67c50bf01 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "vue": "2.4.2" }, "devDependencies": { - "autoprefixer": "^7.1.2", + "autoprefixer": "^7.1.3", "avoriaz": "2.0.0", "babel-cli": "^6.26.0", "babel-core": "^6.26.0", @@ -117,6 +117,6 @@ "webpack": "^3.5.5", "webpack-dev-server": "^2.7.1", "webpack-merge": "^4.1.0", - "zan-doc": "^0.2.5" + "zan-doc": "^0.2.6" } } diff --git a/packages/index.js b/packages/index.js index a3d2fba30..c262f1834 100644 --- a/packages/index.js +++ b/packages/index.js @@ -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, diff --git a/packages/mixins/popup/index.js b/packages/mixins/popup/index.js index cb98e2638..52317cbe2 100644 --- a/packages/mixins/popup/index.js +++ b/packages/mixins/popup/index.js @@ -99,6 +99,7 @@ export default { * 显示popup */ open() { + /* istanbul ignore if */ if (this.$isServer) return; if (this.opened) return; diff --git a/packages/pay-order/index.vue b/packages/pay-order/index.vue new file mode 100644 index 000000000..c0d97122c --- /dev/null +++ b/packages/pay-order/index.vue @@ -0,0 +1,63 @@ + + + diff --git a/packages/vant-css/src/index.css b/packages/vant-css/src/index.css index 04bb59827..89a4b636a 100644 --- a/packages/vant-css/src/index.css +++ b/packages/vant-css/src/index.css @@ -33,3 +33,4 @@ @import './notice-bar.css'; @import './switch-cell.css'; @import './express-way.css'; +@import './pay-order.css'; diff --git a/packages/vant-css/src/pay-order.css b/packages/vant-css/src/pay-order.css new file mode 100644 index 000000000..f674c6f04 --- /dev/null +++ b/packages/vant-css/src/pay-order.css @@ -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; + } + } +} diff --git a/test/unit/specs/pay-order.spec.js b/test/unit/specs/pay-order.spec.js new file mode 100644 index 000000000..6dab66ebf --- /dev/null +++ b/test/unit/specs/pay-order.spec.js @@ -0,0 +1,98 @@ +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: '提交订单', + buttonType: 'default' + } + }); + + 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: { + 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: { + 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); + }); +}); diff --git a/test/unit/specs/popup.spec.js b/test/unit/specs/popup.spec.js index 202cfbdb5..250109f50 100644 --- a/test/unit/specs/popup.spec.js +++ b/test/unit/specs/popup.spec.js @@ -1,5 +1,6 @@ import Popup from 'packages/popup'; import { mount } from 'avoriaz'; +import { triggerTouch } from '../utils'; describe('Popup', () => { let wrapper; @@ -57,4 +58,60 @@ describe('Popup', () => { expect(wrapper.hasClass('van-popup')).to.be.true; expect(wrapper.instance().currentTransition).to.equal('popup-fade'); }); + + it('popup prevent scroll', (done) => { + wrapper = mount(Popup, { + propsData: { + preventScroll: true, + value: true + } + }); + + expect(wrapper.hasClass('van-popup')).to.be.true; + + setTimeout(() => { + expect(wrapper.data().currentValue).to.be.true; + wrapper.vm.value = false; + triggerTouch(document, 'touchstart', 0, 0); + triggerTouch(document, 'touchmove', 0, 10); + triggerTouch(document, 'touchmove', 0, 30); + triggerTouch(document, 'touchmove', 0, -30); + + setTimeout(() => { + expect(wrapper.data().currentValue).to.be.false; + done(); + }, 300); + }, 300); + }); + + it('popup modal', (done) => { + wrapper = mount(Popup, { + propsData: { + preventScroll: true, + value: true + } + }); + + wrapper.vm.$on('input', val => { + wrapper.vm.value = val; + }); + + expect(wrapper.hasClass('van-popup')).to.be.true; + + const modal = document.querySelector('.van-modal'); + + setTimeout(() => { + triggerTouch(modal, 'touchstart', 0, 0); + triggerTouch(modal, 'touchmove', 0, 10); + triggerTouch(modal, 'touchmove', 0, 30); + triggerTouch(modal, 'touchmove', 0, -30); + expect(modal).to.exist; + + modal.click(); + setTimeout(() => { + expect(wrapper.data().currentValue).to.be.false; + done(); + }, 300); + }, 300); + }); }); diff --git a/yarn.lock b/yarn.lock index 65dac4f42..361847594 100644 --- a/yarn.lock +++ b/yarn.lock @@ -334,15 +334,15 @@ autoprefixer@^6.3.1: postcss "^5.2.16" postcss-value-parser "^3.2.3" -autoprefixer@^7.1.2: - version "7.1.2" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-7.1.2.tgz#fbeaf07d48fd878e0682bf7cbeeade728adb2b18" +autoprefixer@^7.1.3: + version "7.1.3" + resolved "https://registry.npmjs.org/autoprefixer/-/autoprefixer-7.1.3.tgz#0e8d337976d6f13644db9f8813b4c42f3d1ccc34" dependencies: - browserslist "^2.1.5" - caniuse-lite "^1.0.30000697" + browserslist "^2.4.0" + caniuse-lite "^1.0.30000718" normalize-range "^0.1.2" num2fraction "^1.2.2" - postcss "^6.0.6" + postcss "^6.0.10" postcss-value-parser "^3.2.3" avoriaz@2.0.0: @@ -1204,13 +1204,20 @@ browserslist@^1.3.6, browserslist@^1.5.2, browserslist@^1.7.6: caniuse-db "^1.0.30000639" electron-to-chromium "^1.2.7" -browserslist@^2.1.2, browserslist@^2.1.5: +browserslist@^2.1.2: version "2.3.3" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.3.3.tgz#2b0cabc4d28489f682598605858a0782f14b154c" dependencies: caniuse-lite "^1.0.30000715" electron-to-chromium "^1.3.18" +browserslist@^2.4.0: + version "2.4.0" + resolved "https://registry.npmjs.org/browserslist/-/browserslist-2.4.0.tgz#693ee93d01e66468a6348da5498e011f578f87f8" + dependencies: + caniuse-lite "^1.0.30000718" + electron-to-chromium "^1.3.18" + buffer-indexof@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.0.tgz#f54f647c4f4e25228baa656a2e57e43d5f270982" @@ -1304,10 +1311,14 @@ caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639: version "1.0.30000715" resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000715.tgz#0b9b5c795950dfbaf301a8806bafe87f126da8ca" -caniuse-lite@^1.0.30000697, caniuse-lite@^1.0.30000715: +caniuse-lite@^1.0.30000715: version "1.0.30000715" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000715.tgz#c327f5e6d907ebcec62cde598c3bf0dd793fb9a0" +caniuse-lite@^1.0.30000718: + version "1.0.30000718" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000718.tgz#0dd24290beb11310b2d80f6b70a823c2a65a6fad" + caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" @@ -7959,9 +7970,9 @@ yeast@0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419" -zan-doc@^0.2.5: - version "0.2.5" - resolved "https://registry.npmjs.org/zan-doc/-/zan-doc-0.2.5.tgz#4f82e1b75db1a348b57436cd1d4ffb607bc18562" +zan-doc@^0.2.6: + version "0.2.6" + resolved "https://registry.npmjs.org/zan-doc/-/zan-doc-0.2.6.tgz#27cc789460c32f6bed7687e050e2d9063b2725d5" dependencies: cheerio "0.22.0" decamelize "^1.2.0"