Quantity: rename to Stepper

This commit is contained in:
陈嘉涵 2017-09-08 11:36:03 +08:00
parent 378ef55a0a
commit 6ec9d9852a
13 changed files with 72 additions and 384 deletions

View File

@ -8,7 +8,7 @@ export default {
}
</script>
## Card 图文组件
## Card 图文
### 使用指南
``` javascript

View File

@ -74,7 +74,7 @@ export default {
}
</script>
## DeepSelect 分类选择组件
## DeepSelect 分类选择
### 使用指南
``` javascript

View File

@ -73,7 +73,7 @@ export default {
};
</script>
## Popup 弹出菜单
## Popup 弹出
### 使用指南
``` javascript
@ -107,11 +107,11 @@ export default {
```
:::
#### 从不同位置弹出菜单
#### 从不同位置弹出
可以设置`position`属性,`popup`即能从不同位置弹出,`position`的可选值有`top``bottom``right``left`
:::demo 从不同位置弹出菜单
:::demo 从不同位置弹出
```html
<van-button @click="popupShow2 = true;">从下方弹出popup</van-button>
<van-popup v-model="popupShow2" position="bottom" class="van-popup-2">
@ -166,7 +166,7 @@ export default {
| v-model | 当前组件是否显示 | `Boolean` | `false` | - |
| overlay | 是否显示背景遮罩层 | `Boolean` | `true` | - |
| lockOnScroll | 背景是否跟随滚动 | `Boolean` | `false` | - |
| position | 弹出菜单位置 | `String` | - | `top`, `bottom`, `right`, `left` |
| closeOnClickOverlay | 点击遮罩层是否关闭弹出菜单 | `Boolean` | `true` | - |
| transition | 弹出菜单`transition` | `String` | `popup-slide` | |
| position | 弹出位置 | `String` | - | `top`, `bottom`, `right`, `left` |
| closeOnClickOverlay | 点击遮罩层是否关闭弹出 | `Boolean` | `true` | - |
| transition | 弹出`transition` | `String` | `popup-slide` | |
| preventScroll | 是否防止滚动穿透 | `Boolean` | `false` | - |

View File

@ -1,10 +1,10 @@
<style>
.demo-quantity {
.van-quantity {
.demo-stepper {
.van-stepper {
margin-left: 15px;
}
.curr-quantity {
.curr-stepper {
margin: 15px;
}
}
@ -14,20 +14,20 @@
export default {
data() {
return {
quantity1: 1,
quantity2: null,
stepper1: 1,
stepper2: null,
};
}
};
</script>
## Quantity 数量选择
## Stepper 步进器
### 使用指南
``` javascript
import { Quantity } from 'vant';
import { Stepper } from 'vant';
Vue.component(Quantity.name, Quantity);
Vue.component(Stepper.name, Stepper);
```
### 代码演示
@ -36,29 +36,28 @@ Vue.component(Quantity.name, Quantity);
:::demo 基础用法
```html
<van-quantity v-model="quantity1"></van-quantity>
<p class="curr-quantity">当前值:{{ quantity1 }}</p>
<van-stepper v-model="stepper1"></van-stepper>
<p class="curr-stepper">当前值:{{ stepper1 }}</p>
```
:::
#### 禁用Quantity
#### 禁用状态
通过设置`disabled`属性来禁用 stepper
设置`disabled`属性,此时`quantity`不可改变。
:::demo 禁用Quantity
:::demo 禁用状态
```html
<van-quantity v-model="quantity1" disabled></van-quantity>
<van-stepper v-model="stepper1" disabled></van-stepper>
```
:::
#### 高级用法
默认是每次加减为1可以对组件设置`step``min``max``defaultValue`属性
默认是每次加减为1可以对组件设置`step``min``max``defaultValue`属性
:::demo 高级用法
```html
<van-quantity v-model="quantity2" min="5" max="40" step="2" default-value="9"></van-quantity>
<p class="curr-quantity">当前值:{{ quantity2 || 9 }}</p>
<van-stepper v-model="stepper2" min="5" max="40" step="2" default-value="9"></van-stepper>
<p class="curr-stepper">当前值:{{ stepper2 || 9 }}</p>
```
:::

View File

@ -60,16 +60,12 @@ module.exports = {
},
{
"path": "/card",
"title": "Card 图文组件"
"title": "Card 图文"
},
{
"path": "/cell",
"title": "Cell 单元格"
},
{
"path": "/cell-swipe",
"title": "CellSwipe 滑动单元格"
},
{
"path": "/icon",
"title": "Icon 图标"
@ -96,15 +92,15 @@ module.exports = {
},
{
"path": "/popup",
"title": "Popup 弹出菜单"
"title": "Popup 弹出"
},
{
"path": "/progress",
"title": "Progress 进度条"
},
{
"path": "/quantity",
"title": "Quantity 数量选择"
"path": "/stepper",
"title": "Stepper 步进器"
},
{
"path": "/steps",
@ -189,6 +185,10 @@ module.exports = {
{
"groupName": "高阶组件",
"list": [
{
"path": "/cell-swipe",
"title": "CellSwipe 滑动单元格"
},
{
"path": "/switch-cell",
"title": "SwitchCell 开关单元格"
@ -204,7 +204,7 @@ module.exports = {
},
{
"path": "/deep-select",
"title": "DeepSelect 分类选择组件"
"title": "DeepSelect 分类选择"
},
{
"path": "/goods-action",

View File

@ -30,7 +30,7 @@ import Picker from './picker';
import Popup from './popup';
import Progress from './progress';
import PullRefresh from './pull-refresh';
import Quantity from './quantity';
import Stepper from './stepper';
import Radio from './radio';
import RadioGroup from './radio-group';
import Row from './row';
@ -79,7 +79,7 @@ const components = [
Popup,
Progress,
PullRefresh,
Quantity,
Stepper,
Radio,
RadioGroup,
Row,
@ -144,7 +144,7 @@ export {
Popup,
Progress,
PullRefresh,
Quantity,
Stepper,
Radio,
RadioGroup,
Row,

View File

@ -1,23 +1,23 @@
<template>
<div class="van-quantity" :class="{ 'van-quantity--disabled': disabled }">
<div class="van-stepper" :class="{ 'van-stepper--disabled': disabled }">
<button
@click="handleChange('minus')"
class="van-quantity__stepper van-quantity__minus"
class="van-stepper__stepper van-stepper__minus"
:class="{
'van-quantity__minus--disabled': isMinusDisabled
'van-stepper__minus--disabled': isMinusDisabled
}">
</button>
<input
type="text"
class="van-quantity__input"
class="van-stepper__input"
:value="currentValue"
@input="handleInputChange"
:disabled="disabled">
<button
@click="handleChange('plus')"
class="van-quantity__stepper van-quantity__plus"
class="van-stepper__stepper van-stepper__plus"
:class="{
'van-quantity__plus--disabled': isPlusDisabled
'van-stepper__plus--disabled': isPlusDisabled
}">
</button>
</div>
@ -25,7 +25,7 @@
<script>
export default {
name: 'van-quantity',
name: 'van-stepper',
props: {
min: {

View File

@ -23,7 +23,7 @@
@import './tag.css';
@import './tab.css';
@import './image-preview.css';
@import './quantity.css';
@import './stepper.css';
@import './progress.css';
@import './swipe.css';

View File

@ -1,12 +1,12 @@
@import './common/var.css';
.van-quantity {
.van-stepper {
font-size: 0;
&--disabled {
.van-quantity__input,
.van-quantity__minus,
.van-quantity__plus {
.van-stepper__input,
.van-stepper__minus,
.van-stepper__plus {
border-color: $active-color;
}
}

View File

@ -27,7 +27,7 @@ describe('DeepSelect', () => {
});
expect(wrapper.hasClass('van-deep-select')).to.be.true;
expect(wrapper.hasStyle('height', '44px')).to.be.true;
expect(wrapper.propsData().maxHeight).to.equal(200);
expect(wrapper.vm.maxHeight).to.equal(200);
});
it('interact with this component', () => {

View File

@ -1,311 +0,0 @@
import OrderGoods from 'packages/order-goods';
import { mount } from 'avoriaz';
import { DOMChecker } from '../utils';
const item1 = {
img_url: 'https://img.yzcdn.cn/upload_files/2017/07/02/af5b9f44deaeb68000d7e4a711160c53.jpg',
pay_price: 1050,
title: '商品 A',
num: '1'
};
const item2 = {
points_price: 200,
pay_price: 50,
img_url: 'https://img.yzcdn.cn/upload_files/2017/07/02/e89d56cd92ad8ce3b9d8e1babc3758b6.jpg',
title: '商品 B',
num: '15',
sku: [{ v: '商品SKU1' }, { v: '商品SKU2' }]
};
const item3 = {
pay_price: 50,
img_url: 'https://img.yzcdn.cn/upload_files/2017/07/02/e89d56cd92ad8ce3b9d8e1babc3758b6.jpg',
title: '商品 C',
num: '15',
is_presale: true,
delivery_time: '三天后发货',
show_delivery_time: true,
is_presale: true,
is_present: true,
message: {
'留言1': '留言1内容',
'留言2': 'https://img.yzcdn.cn/upload_files/2017/07/02/e89d56cd92ad8ce3b9d8e1babc3758b6.jpg'
}
};
describe('OrderGoods', () => {
let wrapper;
afterEach(() => {
wrapper && wrapper.destroy();
});
it('default', () => {
wrapper = mount(OrderGoods, {
attachToDocument: true,
propsData: {
shopName: '起码运动馆',
price: item1.pay_price,
itemList: [item1],
message: '留言留言'
}
});
DOMChecker(wrapper, {
text: {
'.van-order-goods-header a': '起码运动馆',
'.van-order-goods-price .van-cell__value span': '¥10.50',
'.van-card__title': item1.title,
'.van-card__num': 'x ' + item1.num,
'.van-card__price': '¥10.50'
},
value: {
'.van-order-goods-message textarea': '留言留言'
},
src: {
'.van-card__thumb img': item1.img_url
}
});
});
it('empty list', () => {
wrapper = mount(OrderGoods, {
attachToDocument: true,
propsData: {
itemList: []
}
});
const submitSpyFunc = sinon.spy();
wrapper.vm.$on('clickEmptyButton', submitSpyFunc);
wrapper.find('.van-button')[0].trigger('click');
DOMChecker(wrapper, {
text: {
'.van-order-goods-empty p': '当前没有可购买的商品,请重新选择',
'.van-order-goods-empty button': '返回重新选择'
},
src: {
'.van-order-goods-empty img': 'http://b.yzcdn.cn/v2/image/wap/trade/new_order/empty@2x.png'
}
});
expect(submitSpyFunc.calledOnce).to.be.true;
});
it('empty list config', () => {
wrapper = mount(OrderGoods, {
attachToDocument: true,
propsData: {
emptyIcon: 'https://img.yzcdn.cn/upload_files/2017/07/01/FlIeRrn5bMRoWhcwp4Dp1TmVAXKy.jpg',
emptyMessage: '测试',
emptyButtonText: '测试'
}
});
DOMChecker(wrapper, {
text: {
'.van-order-goods-empty p': '测试',
'.van-order-goods-empty button': '测试'
},
src: {
'.van-order-goods-empty img': 'https://img.yzcdn.cn/upload_files/2017/07/01/FlIeRrn5bMRoWhcwp4Dp1TmVAXKy.jpg'
}
});
});
it('edit message', (done) => {
wrapper = mount(OrderGoods, {
attachToDocument: true,
propsData: {
itemList: [item1],
message: ''
}
});
wrapper.vm.$on('input', val => {
wrapper.vm.message = val;
expect(wrapper.vm.message).to.equal('测试留言');
done();
});
const textarea = wrapper.find('textarea')[0];
textarea.element.value = '测试留言';
textarea.trigger('input');
});
it('message not editable', () => {
wrapper = mount(OrderGoods, {
attachToDocument: true,
propsData: {
itemList: [item1],
message: '留言留言',
messageEditable: false
}
});
DOMChecker(wrapper, {
text: {
'.van-order-goods-message p': '留言留言'
}
});
});
it('message not editable && empty', () => {
wrapper = mount(OrderGoods, {
attachToDocument: true,
propsData: {
itemList: [item1],
message: '',
messageEditable: false
}
});
DOMChecker(wrapper, {
text: {
'.van-order-goods-message p': ''
}
});
});
it('points props', () => {
wrapper = mount(OrderGoods, {
attachToDocument: true,
propsData: {
itemList: [item1],
points: 100
}
});
DOMChecker(wrapper, {
text: {
'.van-order-goods-price .van-cell__value span': '100积分'
}
});
});
it('points prop and price prop', () => {
wrapper = mount(OrderGoods, {
attachToDocument: true,
propsData: {
itemList: [item1],
points: 100,
price: 1050
}
});
DOMChecker(wrapper, {
text: {
'.van-order-goods-price .van-cell__value span': '100积分 + ¥10.50'
}
});
});
it('shopLink prop', () => {
wrapper = mount(OrderGoods, {
attachToDocument: true,
propsData: {
itemList: [item1],
shopLink: 'http://www.youzan.com'
}
});
expect(wrapper.find('.van-order-goods-header a')[0].element.getAttribute('href')).to.equal('http://www.youzan.com');
});
it('item with points', () => {
wrapper = mount(OrderGoods, {
attachToDocument: true,
propsData: {
itemList: [item2]
}
});
DOMChecker(wrapper, {
text: {
'.van-card__price': '200积分 + ¥0.50',
'.van-card__title': item2.title,
'.van-card__num': 'x ' + item2.num
},
src: {
'.van-card__thumb img': item2.img_url
}
});
});
it('presable item with deliveryTime', () => {
wrapper = mount(OrderGoods, {
attachToDocument: true,
propsData: {
itemList: [item3]
}
});
DOMChecker(wrapper, {
text: {
'.van-card__price': '¥0.50',
'.van-card__title': item3.title,
'.van-card__num': 'x ' + item3.num,
'.van-order-goods-card__delivery .van-cell__value span': item3.delivery_time
},
count: {
'.van-order-goods-card__present': 1,
'.van-order-goods-card__tag-green': 1
},
src: {
'.van-card__thumb img': item3.img_url
}
});
});
it('item with message', (done) => {
wrapper = mount(OrderGoods, {
attachToDocument: true,
propsData: {
itemList: [item3]
}
});
DOMChecker(wrapper, {
count: {
'.van-order-goods-card__message-button': 1,
'.van-order-goods-card__message li': 2
},
style: {
'.van-order-goods-card__message': {
'display': 'none'
}
}
});
const messageButton = wrapper.find('.van-order-goods-card__message-button')[0];
messageButton.trigger('click');
setTimeout(function() {
DOMChecker(wrapper, {
noStyle: {
'.van-order-goods-card__message': {
'display': 'none'
}
}
});
done();
}, 300);
});
it('multi items', () => {
wrapper = mount(OrderGoods, {
attachToDocument: true,
propsData: {
itemList: [item1, item2, item3]
}
});
DOMChecker(wrapper, {
count: {
'.van-order-goods-card': 3
}
});
});
});

View File

@ -8,7 +8,7 @@ describe('Search', () => {
wrapper && wrapper.destroy();
});
it('create a quantity', () => {
it('create a stepper', () => {
wrapper = mount(Search);
expect(wrapper.hasClass('van-search')).to.be.true;

View File

@ -1,43 +1,43 @@
import Quantity from 'packages/quantity';
import Stepper from 'packages/stepper';
import { mount } from 'avoriaz';
describe('Quantity', () => {
describe('Stepper', () => {
let wrapper;
afterEach(() => {
wrapper && wrapper.destroy();
});
it('create a quantity', () => {
wrapper = mount(Quantity, {
it('create a stepper', () => {
wrapper = mount(Stepper, {
propsData: {
defaultValue: 1
}
});
expect(wrapper.hasClass('van-quantity')).to.be.true;
expect(wrapper.hasClass('van-stepper')).to.be.true;
expect(wrapper.data().currentValue).to.equal(1);
const plusButton = wrapper.find('.van-quantity__plus')[0];
const plusButton = wrapper.find('.van-stepper__plus')[0];
plusButton.trigger('click');
expect(wrapper.data().currentValue).to.equal(2);
const minusButton = wrapper.find('.van-quantity__minus')[0];
const minusButton = wrapper.find('.van-stepper__minus')[0];
minusButton.trigger('click');
expect(wrapper.data().currentValue).to.equal(1);
});
it('create a disabled quantity', (done) => {
wrapper = mount(Quantity, {
it('create a disabled stepper', (done) => {
wrapper = mount(Stepper, {
propsData: {
disabled: true
}
});
expect(wrapper.hasClass('van-quantity')).to.be.true;
const minusButton = wrapper.find('.van-quantity__minus')[0];
expect(minusButton.hasClass('van-quantity__minus--disabled')).to.be.true;
expect(wrapper.hasClass('van-stepper')).to.be.true;
const minusButton = wrapper.find('.van-stepper__minus')[0];
expect(minusButton.hasClass('van-stepper__minus--disabled')).to.be.true;
const eventStub = sinon.stub(wrapper.vm, '$emit');
minusButton.trigger('click');
@ -48,8 +48,8 @@ describe('Quantity', () => {
done();
});
const plusButton = wrapper.find('.van-quantity__plus')[0];
expect(plusButton.hasClass('van-quantity__plus--disabled')).to.be.true;
const plusButton = wrapper.find('.van-stepper__plus')[0];
expect(plusButton.hasClass('van-stepper__plus--disabled')).to.be.true;
plusButton.trigger('click');
@ -60,14 +60,14 @@ describe('Quantity', () => {
});
});
it('update quantity value use v-model', (done) => {
wrapper = mount(Quantity, {
it('update stepper value use v-model', (done) => {
wrapper = mount(Stepper, {
propsData: {
value: 1
}
});
expect(wrapper.hasClass('van-quantity')).to.be.true;
expect(wrapper.hasClass('van-stepper')).to.be.true;
const eventStub = sinon.stub(wrapper.vm, '$emit');
wrapper.vm.value = 2;
@ -80,14 +80,14 @@ describe('Quantity', () => {
});
it('correct value when value is not correct', (done) => {
wrapper = mount(Quantity, {
wrapper = mount(Stepper, {
propsData: {
value: 50,
max: 30
}
});
expect(wrapper.hasClass('van-quantity')).to.be.true;
expect(wrapper.hasClass('van-stepper')).to.be.true;
expect(wrapper.vm.currentValue).to.equal(30);
const eventStub = sinon.stub(wrapper.vm, '$emit');
@ -101,13 +101,13 @@ describe('Quantity', () => {
});
it('handle when input change', (done) => {
wrapper = mount(Quantity, {
wrapper = mount(Stepper, {
propsData: {
value: 1
}
});
const input = wrapper.find('.van-quantity__input')[0];
const input = wrapper.find('.van-stepper__input')[0];
input.element.value = 2;
input.trigger('input');