Merge branch 'dev' into feature/sku_migration

This commit is contained in:
niunai 2017-09-08 16:51:14 +08:00
commit 6da45f69e6
52 changed files with 477 additions and 2312 deletions

View File

@ -31,10 +31,6 @@ export default {
name: '支付宝支付',
loading: true
},
{
name: '有赞E卡',
subname: '剩余260.50元)'
},
{
name: '信用卡支付'
},
@ -90,10 +86,6 @@ export default {
name: '支付宝支付',
loading: true
},
{
name: '有赞E卡',
subname: '剩余260.50元)'
},
{
name: '信用卡支付'
},
@ -139,10 +131,6 @@ export default {
name: '支付宝支付',
loading: true
},
{
name: '有赞E卡',
subname: '剩余260.50元)'
},
{
name: '信用卡支付'
},

View File

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

View File

@ -31,12 +31,12 @@
**非兼容更新和新特性:**
- PayOrder component add tip slot [\#105](https://github.com/youzan/vant/pull/105) ([Raistlin916](https://github.com/Raistlin916))
- SubmitBar component add tip slot [\#105](https://github.com/youzan/vant/pull/105) ([Raistlin916](https://github.com/Raistlin916))
- Checkbox: support listen to change event [\#104](https://github.com/youzan/vant/pull/104) ([chenjiahan](https://github.com/chenjiahan))
- add GoodsAction component [\#102](https://github.com/youzan/vant/pull/102) ([chenjiahan](https://github.com/chenjiahan))
- add InvalidGoods component [\#100](https://github.com/youzan/vant/pull/100) ([chenjiahan](https://github.com/chenjiahan))
- add OrderGoods component [\#99](https://github.com/youzan/vant/pull/99) ([chenjiahan](https://github.com/chenjiahan))
- add PayOrder component [\#98](https://github.com/youzan/vant/pull/98) ([chenjiahan](https://github.com/chenjiahan))
- add SubmitBar component [\#98](https://github.com/youzan/vant/pull/98) ([chenjiahan](https://github.com/chenjiahan))
**修复:**
@ -44,7 +44,7 @@
**合并的 Pull Request (可能有不兼容改动):**
- Add deep-select component and fix a popup bug. [\#103](https://github.com/youzan/vant/pull/103) ([Tinysymphony](https://github.com/Tinysymphony))
- Add tree-select component and fix a popup bug. [\#103](https://github.com/youzan/vant/pull/103) ([Tinysymphony](https://github.com/Tinysymphony))
- Doc: update Step/Loading/Tag/Badge documents [\#101](https://github.com/youzan/vant/pull/101) ([chenjiahan](https://github.com/chenjiahan))
## [v0.8.7](https://github.com/youzan/vant/tree/v0.8.7) (2017-08-29)

View File

@ -1,4 +1,4 @@
## OrderCoupon 下单页优惠券
## Coupon 优惠券选择器
<script>
import { Toast } from 'packages';
@ -61,10 +61,10 @@ export default {
### 使用指南
``` javascript
import { OrderCoupon, OrderCouponList } from 'vant';
import { CouponCell, CouponList } from 'vant';
Vue.component(OrderCoupon.name, OrderCoupon);
Vue.component(OrderCouponList.name, OrderCouponList);
Vue.component(CouponCell.name, CouponCell);
Vue.component(CouponList.name, CouponList);
```
### 代码演示
@ -74,25 +74,25 @@ Vue.component(OrderCouponList.name, OrderCouponList);
:::demo 基础用法
```html
<!-- 优惠券单元格 -->
<van-order-coupon
<van-coupon-cell
:coupons="coupons"
:chosen-coupon="chosenCoupon"
@click="showList = true"
></van-order-coupon>
></van-coupon-cell>
<!-- 优惠券列表 -->
<van-order-coupon-list
<van-coupon-list
v-model="showList"
:coupons="coupons"
:chosen-coupon="chosenCoupon"
:disabled-coupons="disabledCoupons"
@change="onChange"
@exchange="onExchange"
></van-order-coupon-list>
></van-coupon-list>
```
```javascript
const mockCoupon = {
const coupon = {
available: 1,
discount: 0,
denominations: 150,
@ -109,8 +109,8 @@ export default {
data() {
return {
chosenCoupon: -1,
coupons: [mockCoupon],
disabledCoupons: [mockCoupon]
coupons: [coupon],
disabledCoupons: [coupon]
}
},
@ -119,22 +119,23 @@ export default {
this.chosenCoupon = index;
},
onExchange(code) {
this.coupons.push(mockCoupon);
this.coupons.push(coupon);
}
}
}
```
:::
### OrderCoupon API
### CouponCell API
| 参数 | 说明 | 类型 | 默认值 | 必须 |
|-----------|-----------|-----------|-------------|-------------|
| title | 单元格标题 | `String` | `优惠` | - |
| chosenCoupon | 当前选中优惠券的索引 | `Number` | `-1` | - |
| coupons | 可用优惠券列表 | `Array` | `[]` | - |
| editable | 能否切换优惠券 | `Boolean` | `true` | - |
### OrderCouponList API
### CouponList API
| 参数 | 说明 | 类型 | 默认值 | 必须 |
|-----------|-----------|-----------|-------------|-------------|
@ -149,7 +150,7 @@ export default {
| disabledListTitle | 不可用券列表标题 | `String` | 不可用优惠 | - |
| inputPlaceholder | 输入框文字提示 | `String` | 请输入优惠码 | - |
### OrderCouponList Event
### CouponList Event
| 事件名 | 说明 | 参数 |
|-----------|-----------|-----------|

View File

@ -1,118 +0,0 @@
## ExpressWay 配送方式
<script>
import { Toast } from 'packages';
export default {
data() {
return {
currentExpressType: 1,
expressList: [{
'postage': 10050,
'postage_desc': '由商家门店提供配送服务, 起送价 0.01 元',
'postage_title': '同城配送',
'express_type': 1
}, {
'postage': 0,
'postage_desc': '由商家选择合作快递为您服务',
'postage_title': '快递发货',
'express_type': 2,
'postage_warn_desc': '3天后发货'
}]
};
},
methods: {
onChange(item, index) {
Toast('配送方式更换为:' + item.postage_title);
}
}
}
</script>
### 使用指南
``` javascript
import { ExpressWay } from 'vant';
Vue.component(ExpressWay.name, ExpressWay);
```
### 代码演示
#### 基础用法
:::demo 基础用法
```html
<van-cell-group>
<van-express-way
v-model="currentExpressType"
:express-list="expressList"
@change="onChange"
></van-express-way>
</van-cell-group>
```
```javascript
export default {
data() {
return {
currentExpressType: 1,
expressList: [{
'postage': 10050,
'postage_desc': '由商家门店提供配送服务, 起送价 0.01 元',
'postage_title': '同城配送',
'express_type': 1
}]
};
},
methods: {
onChange(item) {
Toast(`配送方式更换为:${item.postage_title}`);
}
}
}
```
:::
#### 不可修改配送方式
:::demo 不可修改配送方式
```html
<van-cell-group>
<van-express-way
:value="1"
:express-list="expressList"
:editable="false"
@change="onChange"
></van-express-way>
</van-cell-group>
```
:::
### API
| 参数 | 说明 | 类型 | 默认值 | 必须 |
|-----------|-----------|-----------|-------------|-------------|
| v-model | 当前选择的配送类型 | `Number` | | 是 |
| expressList | 配送方式列表数据 | `Array` | | 是 |
| cellTitle | Cell 标题 | `String` | `配送方式` | 否 |
| actionsheetTitle | Actionsheet 标题 | `String` | `配送方式` | 否 |
| editable | 能否修改配送方式 | `Boolean` | `true` | 否 |
### 数据格式
#### expressList中的配送方式字段说明
| key | 说明 | 类型 |
|-----------|-----------|-----------|
| postage | 运费,以分为单位 | Number |
| postage_title | 配送方式 | String |
| postage_desc | 描述信息 | String |
| express_type | 配送类型 | Number |
| postage_warn_desc | 提示信息 | String |
### Event
| 事件名 | 说明 | 参数 |
|-----------|-----------|-----------|
| change | 修改配送方式时触发 | item: 对应的数据, index对应的索引 |

View File

@ -21,7 +21,7 @@ export default {
}
</style>
## GoodsAction 商品操作
## GoodsAction 商品页行动点
### 使用指南
``` javascript

View File

@ -1,81 +0,0 @@
## InvalidGoods 不可用商品列表
<script>
const item = {
sku: [{ v: '商品SKU1' }, { v: '商品SKU2' }],
num: 2,
sku_id: 123,
title: "商品名称",
price: 12200,
unavailable_desc: '超出配送区域',
img_url: 'https://img.yzcdn.cn/upload_files/2017/06/29/FnPSAKkEeh4FnDA09oIbmnlzWQrw.png',
};
export default {
data() {
return {
goods: [item, item, item]
}
}
}
</script>
### 使用指南
``` javascript
import { InvalidGoods } from 'vant';
Vue.component(InvalidGoods.name, InvalidGoods);
```
### 代码演示
#### 基础用法
:::demo 基础用法
```html
<van-invalid-goods :goods="goods" />
```
```javascript
const item = {
num: 2,
sku_id: 123,
price: 12200,
title: "商品名称",
img_url: 'https://img.yzcdn.cn/...',
unavailable_desc: '超出配送区域',
sku: [
{ v: '商品SKU1' },
{ v: '商品SKU2' }
]
};
export default {
data() {
return {
goods: [item, item, item]
}
}
}
```
:::
### API
| 参数 | 说明 | 类型 | 默认值 | 必须 |
|-----------|-----------|-----------|-------------|-------------|
| goods | 商品数据 | `Array` | | 是 |
| title | 标题 | `String` | `以下商品无法一起购买,点击查看原因` | 否 |
| actionsheetTitle | 弹出层标题 | `String` | `以下商品无法一起下单` | 否 |
### 数据格式
#### data中的商品字段说明
| key | 说明 | 类型 |
|-----------|-----------|-----------|
| num | 商品数量 | `Number` |
| sku_id | 商品 id | `Number` |
| price | 商品价格,以分为单位 | `Number` |
| title | 商品标题 | `String` |
| img_url | 商品图片 url | `String` |
| unavailable_desc | 不可用原因 | `String` |
| sku | 商品 sku | `Array` |

View File

@ -0,0 +1,52 @@
## NavBar 导航栏
### 使用指南
``` javascript
import { NavBar } from 'vant';
Vue.component(NavBar.name, NavBar);
```
### 代码演示
#### 基础用法
:::demo 基础用法
```html
<van-nav-bar
title="标题"
left-text="返回"
right-text="按钮"
left-arrow
/>
```
:::
#### 高级用法
通过 slot 定制内容
:::demo 高级用法
```html
<van-nav-bar title="标题" left-text="返回" left-arrow>
<van-icon name="search" slot="right" />
</van-nav-bar>
```
:::
### API
| 参数 | 说明 | 类型 | 默认值 | 可选值 |
|-----------|-----------|-----------|-------------|-------------|
| title | 标题 | `String` | `''` | - |
| left-text | 左侧文案 | `String` | `''` | - |
| right-text | 右侧文案 | `String` | `''` | - |
| left-arrow | 是否显示左侧箭头 | `Boolean` | `false` | - |
| fixed | 是否固定在顶部 | `Boolean` | `false` | - |
### Slot
| name | 描述 |
|-----------|-----------|
| title | 自定义标题 |
| left | 自定义左侧区域内容 |
| right | 自定义右侧区域内容 |

View File

@ -1,229 +0,0 @@
## OrderGoods 下单页商品列表
<script>
const item1 = {
img_url: '//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: '//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: '//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'
}
};
export default {
data() {
return {
itemList1: [item1],
itemList2: [item2],
itemList3: [item3],
itemListMulti: [item1, item2, item3],
emptyItemList: [],
message1: '',
message2: '',
message3: '',
message4: ''
}
}
}
</script>
### 使用指南
``` javascript
import { OrderGoods } from 'vant';
Vue.component(OrderGoods.name, OrderGoods);
```
### 代码演示
#### 基础用法
:::demo 基础用法
```html
<van-order-goods
v-model="message1"
shop-name="起码运动馆"
:price="1050"
:item-list="itemList1"
/>
```
```javascript
export default {
data() {
return {
message1: '',
itemList1: [{
img_url: '//img.yzcdn.cn/...',
pay_price: 1050,
title: '商品 A',
num: '1'
}]
}
}
}
```
:::
#### 积分商品
:::demo 积分商品
```html
<van-order-goods
v-model="message2"
shop-name="起码运动馆"
:item-list="itemList2"
:price="50"
:points="200"
/>
```
```javascript
export default {
data() {
return {
message2: '',
itemList2: [{
points_price: 200,
pay_price: 50,
img_url: '//img.yzcdn.cn/...',
title: '商品 B',
num: '15',
sku: [
{ v: '商品SKU1' },
{ v: '商品SKU2' }
]
}]
}
}
}
```
:::
#### 预售商品
:::demo 预售商品
```html
<van-order-goods
v-model="message3"
shop-name="起码运动馆"
:price="1050"
:item-list="itemList3"
/>
```
```javascript
export default {
data() {
return {
message3: '',
itemList3: [{
pay_price: 50,
img_url: '//img.yzcdn.cn/...',
title: '商品 C',
num: '15',
delivery_time: '三天后发货',
show_delivery_time: true,
is_presale: true,
is_present: true
}]
}
}
}
```
:::
#### 商品为空
:::demo 商品为空
```html
<van-order-goods shop-name="起码运动馆" :item-list="[]" />
```
:::
#### 多个商品
:::demo 多个商品
```html
<van-order-goods
v-model="message4"
shop-name="起码运动馆"
:item-list="itemListMulti"
:price="1050"
:message-editable="false"
/>
```
:::
### API
| 参数 | 说明 | 类型 | 默认值 |
|-----------|-----------|-----------|-------------|
| shop-name | 店铺名称 | `String` | |
| shop-link | 店铺链接 | `String` | |
| header-icon | 店铺名称左侧的图标类型 | `String` | `shop` |
| header-badge | 店铺名称右侧的徽章链接 | `String` | |
| item-list | 商品列表 | `Array` | `[]` |
| empty-icon | 商品列表为空时的图标 | `String` | |
| empty-message | 商品列表为空时的提示文案 | `String` | `当前没有可购买的商品,请重新选择` |
| empty-button-text | 商品列表为空时的按钮文案 | `String` | `返回重新选择` |
| v-model | 买家留言 | `String` | `''` |
| show-total-price | 是否显示价格栏 | `Boolean` | `true` |
| show-message | 是否显示留言栏 | `Boolean` | `true` |
| message-editable | 留言是否可以编辑 | `Boolean` | `true` |
| price | 合计金额(单位分) | `Number` | |
| points | 合计积分 | `Number` | |
### 数据格式
#### itemList 中的配送方式字段说明
| key | 说明 | 类型 |
|-----------|-----------|-----------|
| title | 商品名称 | `String` |
| img_url | 图片地址 | `String` |
| delivery_time | 发货时间 | `String` |
| num | 商品数量 | `Number` |
| points_price | 积分价格 | `Number` |
| pay_price单位分 | 金额 | `Number` |
| sku | 商品 sku | `Array` |
| message | 商品留言 | `Array` |
| is_presale | 是否为预售 | `Boolean` |
| is_present | 是否为赠品 | `Boolean` |
| is_period_buy | 是否为周期购 | `Boolean` |
| show_delivery_time | 是否显示发货时间 | `Boolean` |
### Event
| 事件名 | 说明 | 参数 |
|-----------|-----------|-----------|
| clickEmptyButton | 点击商品为空时的按钮时触发 | - |
### Slot
| name | 描述 |
|-----------|-----------|
| 默认 | 在商品列表和留言之间插入内容 |
| top | 在标题和商品列表之间插入内容 |
| bottom | 在合计价格下方插入内容 |

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

@ -1,4 +1,4 @@
## PayOrder 提交订单栏
## SubmitBar 提交订单栏
<script>
import { Toast } from 'packages';
@ -16,8 +16,8 @@ export default {
</script>
<style>
.demo-pay-order {
.van-pay-order {
.demo-submit-bar {
.van-submit-bar {
position: relative;
}
.van-edit-address {
@ -28,9 +28,9 @@ export default {
### 使用指南
``` javascript
import { PayOrder } from 'vant';
import { SubmitBar } from 'vant';
Vue.component(PayOrder.name, PayOrder);
Vue.component(SubmitBar.name, SubmitBar);
```
### 代码演示
@ -39,7 +39,7 @@ Vue.component(PayOrder.name, PayOrder);
:::demo 基础用法
```html
<van-pay-order
<van-submit-bar
:price="3050"
button-text="提交订单"
@submit="onClickButton"
@ -52,7 +52,7 @@ Vue.component(PayOrder.name, PayOrder);
:::demo 禁用状态
```html
<van-pay-order
<van-submit-bar
disabled
:price="3050"
button-text="提交订单"
@ -66,7 +66,7 @@ Vue.component(PayOrder.name, PayOrder);
加载状态下不会触发`submit`事件
:::demo 加载状态
```html
<van-pay-order
<van-submit-bar
loading
:price="3050"
button-text="提交订单"
@ -79,7 +79,7 @@ Vue.component(PayOrder.name, PayOrder);
提示文案中的额外操作和说明
:::demo 提示文案中添加操作
```html
<van-pay-order
<van-submit-bar
:price="3050"
button-text="提交订单"
@submit="onClickButton"
@ -87,7 +87,7 @@ Vue.component(PayOrder.name, PayOrder);
<span slot="tip">
您的收货地址不支持同城送, <span class="van-edit-address" @click="onClickEditAddress">修改地址 ></span>
</span>
</van-pay-order>
</van-submit-bar>
```
:::

View File

@ -74,13 +74,13 @@ export default {
}
</script>
## DeepSelect 分类选择组件
## TreeSelect 分类选择
### 使用指南
``` javascript
import { DeepSelect } from 'vant';
import { TreeSelect } from 'vant';
Vue.component(DeepSelect.name, DeepSelect);
Vue.component(TreeSelect.name, TreeSelect);
```
### 代码演示
@ -89,13 +89,13 @@ Vue.component(DeepSelect.name, DeepSelect);
:::demo 基础用法
```html
<van-deep-select
<van-tree-select
:items="items"
:main-active-index="mainActiveIndex"
:active-id="activeId"
@navclick="onNavClick"
@itemclick="onItemClick"
></van-deep-select>
></van-tree-select>
```
```javascript

View File

@ -11,6 +11,11 @@ import docConfig from './doc.config';
export default {
data() {
if (location.host === 'www.youzanyun.com') {
const group = docConfig['zh-CN'].nav[0].groups[0];
group.list = group.list.filter(item => item.title !== '业务组件');
}
return {
simulator: this.getSimulatorPath(),
config: docConfig['zh-CN']

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 图标"
@ -86,6 +82,10 @@ module.exports = {
"path": "/loading",
"title": "Loading 加载"
},
{
"path": "/nav-bar",
"title": "NavBar 导航栏"
},
{
"path": "/notice-bar",
"title": "NoticeBar 通告栏"
@ -96,20 +96,28 @@ module.exports = {
},
{
"path": "/popup",
"title": "Popup 弹出菜单"
"title": "Popup 弹出"
},
{
"path": "/progress",
"title": "Progress 进度条"
},
{
"path": "/quantity",
"title": "Quantity 数量选择"
"path": "/search",
"title": "Search 搜索"
},
{
"path": "/stepper",
"title": "Stepper 步进器"
},
{
"path": "/steps",
"title": "Steps 步骤条"
},
{
"path": "/swipe",
"title": "Swipe 轮播"
},
{
"path": "/tab",
"title": "Tab 标签"
@ -118,14 +126,6 @@ module.exports = {
"path": "/tag",
"title": "Tag 标记"
},
{
"path": "/swipe",
"title": "Swipe 轮播"
},
{
"path": "/search",
"title": "Search 搜索"
},
{
"path": "/waterfall",
"title": "Waterfall 瀑布流"
@ -187,47 +187,44 @@ module.exports = {
]
},
{
"groupName": "业务组件",
"groupName": "高阶组件",
"list": [
{
"path": "/deep-select",
"title": "DeepSelect 分类选择组件"
},
{
"path": "/express-way",
"title": "ExpressWay 配送方式"
},
{
"path": "/goods-action",
"title": "GoodsAction 商品操作"
},
{
"path": "/sku",
"title": "Sku 商品规格弹层"
},
{
"path": "/invalid-goods",
"title": "InvalidGoods 不可用商品列表"
},
{
"path": "/order-coupon",
"title": "OrderCoupon 下单页优惠券"
},
{
"path": "/order-goods",
"title": "OrderGoods 下单页商品列表"
},
{
"path": "/pay-order",
"title": "PayOrder 提交订单栏"
"path": "/cell-swipe",
"title": "CellSwipe 滑动单元格"
},
{
"path": "/switch-cell",
"title": "SwitchCell 开关单元格"
},
{
"path": "/tree-select",
"title": "TreeSelect 分类选择"
},
]
},
{
"groupName": "业务组件",
"list": [
{
"path": "/area",
"title": "Area 省市区选择"
},
{
"path": "/coupon",
"title": "Coupon 优惠券选择器"
},
{
"path": "/goods-action",
"title": "GoodsAction 商品页行动点"
},
{
"path": "/submit-bar",
"title": "SubmitBar 提交订单栏"
},
{
"path": "/sku",
"title": "Sku 商品规格弹层"
}
]
}

View File

@ -1,7 +1,7 @@
<template>
<div class="van-order-coupon">
<div class="van-coupon-cell">
<van-cell-group>
<van-cell title="优惠" :isLink="editable" @click="$emit('click')">
<van-cell :title="title" :isLink="editable" @click="$emit('click')">
<div v-if="coupons[chosenCoupon]">
<h2>{{ amount }}</h2>
<span>{{ coupons[chosenCoupon].condition }}</span>
@ -17,7 +17,7 @@ import Cell from '../cell';
import CellGroup from '../cell-group';
export default {
name: 'van-order-coupon',
name: 'van-coupon-cell',
components: {
[Cell.name]: Cell,
@ -29,6 +29,10 @@ export default {
},
props: {
title: {
type: String,
default: '优惠'
},
coupons: {
type: Array,
default: () => []

View File

@ -1,17 +1,17 @@
<template>
<div :class="['van-order-coupon-coupon', { 'van-order-coupon-coupon--disabled': disabled }]">
<div class="van-order-coupon-coupon__head">
<div class="van-order-coupon-coupon__lines"></div>
<div class="van-order-coupon-coupon__gradient">
<div :class="['van-coupon-item', { 'van-coupon-item--disabled': disabled }]">
<div class="van-coupon-item__head">
<div class="van-coupon-item__lines"></div>
<div class="van-coupon-item__gradient">
<h2 v-html="faceAmount" />
<p>{{ conditionMessage }}</p>
</div>
</div>
<div class="van-order-coupon-coupon__body">
<div class="van-coupon-item__body">
<h2>{{ data.name }}</h2>
<span>{{ validPeriod }}</span>
<p v-if="disabled && data.reason">{{ data.reason }}</p>
<div class="van-order-coupon-coupon__corner" v-if="chosen">
<div class="van-coupon-item__corner" v-if="chosen">
<van-icon name="success" />
</div>
</div>
@ -22,7 +22,7 @@
import Icon from '../icon';
export default {
name: 'van-order-coupon-coupon',
name: 'van-coupon-item',
components: {
[Icon.name]: Icon

View File

@ -1,11 +1,11 @@
<template>
<van-popup v-model="showPopup" position="bottom" class="van-order-coupon-list">
<van-cell-group class="van-order-coupon-list__top">
<van-popup v-model="showPopup" position="bottom" class="van-coupon-list">
<van-cell-group class="van-coupon-list__top">
<van-field v-model="exchangeCode" :placeholder="inputPlaceholder" :maxlength="20" />
<van-button size="small" type="danger" class="van-order-coupon-list__exchange" :disabled="exchangeButtonDisabled || !exchangeCode.length" @click="onClickExchangeButton">{{ exchangeButtonText }}</van-button>
<van-button size="small" type="danger" class="van-coupon-list__exchange" :disabled="exchangeButtonDisabled || !exchangeCode.length" @click="onClickExchangeButton">{{ exchangeButtonText }}</van-button>
</van-cell-group>
<div class="van-order-coupon-list__list" ref="list">
<van-order-coupon-coupon
<div class="van-coupon-list__list" ref="list">
<van-coupon-item
ref="card"
v-for="(item, index) in coupons"
:key="item.id || item.name"
@ -14,27 +14,27 @@
@click.native="onClickCoupon(index)"
/>
<h3 v-if="disabledCoupons.length">{{ disabledListTitle }}</h3>
<van-order-coupon-coupon
<van-coupon-item
disabled
v-for="item in disabledCoupons"
:key="item.id || item.name"
:data="item"
/>
</div>
<div class="van-order-coupon-list__close van-hairline--top" @click="onClickNotUse">{{ closeButtonText }}</div>
<div class="van-coupon-list__close van-hairline--top" @click="onClickNotUse">{{ closeButtonText }}</div>
</van-popup>
</template>
<script>
import Cell from '../cell';
import CellGroup from '../cell-group';
import Coupon from './Coupon';
import Item from './Item';
import Field from '../field';
import Popup from '../popup';
import Button from '../button';
export default {
name: 'van-order-coupon-list',
name: 'van-coupon-list',
components: {
[Button.name]: Button,
@ -42,7 +42,7 @@ export default {
[CellGroup.name]: CellGroup,
[Field.name]: Field,
[Popup.name]: Popup,
[Coupon.name]: Coupon
[Item.name]: Item
},
model: {

View File

@ -1,32 +0,0 @@
<template>
<van-cell class="van-express-way-option" @click="$emit('change')">
<van-radio :name="data.express_type" :value="currentExpressWay" />
<div class="van-express-way-option__content">
<h3 class="van-express-way-option__title">
<span>{{ data.postage_title }}</span>
<span>{{ data.postage }}</span>
</h3>
<p>{{ data.postage_desc }}</p>
<div class="van-express-way-option__warn" v-if="data.postage_warn_desc">{{ data.postage_warn_desc }}</div>
</div>
</van-cell>
</template>
<script>
import Cell from '../cell';
import Radio from '../radio';
export default {
name: 'van-express-way-option',
components: {
[Cell.name]: Cell,
[Radio.name]: Radio
},
props: {
data: Object,
currentExpressWay: Number
}
};
</script>

View File

@ -1,100 +0,0 @@
<template>
<van-cell class="van-express-way">
<van-actionsheet v-if="computedEditable" v-model="showActionsheet" :title="actionsheetTitle" >
<van-cell-group>
<van-express-way-option
v-for="(item, index) in computedList"
:key="item.express_type"
:data="item"
:currentExpressWay="value"
@change="onSelectExpressWay(item, index)"
/>
</van-cell-group>
</van-actionsheet>
<van-cell :title="cellTitle" :isLink="computedEditable" @click="showActionsheet = computedEditable">
<p class="van-express-way__fee">{{ currentOption.postage }}</p>
<p class="van-express-way__type">{{ currentOption.postage_title }}</p>
</van-cell>
</van-cell>
</template>
<script>
import Option from './Option';
import Cell from '../cell';
import CellGroup from '../cell-group';
import Actionsheet from '../actionsheet';
export default {
name: 'van-express-way',
components: {
[Option.name]: Option,
[Cell.name]: Cell,
[CellGroup.name]: CellGroup,
[Actionsheet.name]: Actionsheet
},
props: {
value: {
type: Number,
required: true
},
expressList: {
type: Array,
required: true
},
cellTitle: {
type: String,
default: '配送方式'
},
actionsheetTitle: {
type: String,
default: '配送方式'
},
editable: {
type: Boolean,
default: true
}
},
data() {
return {
showActionsheet: false
};
},
computed: {
computedList() {
return this.expressList.map(item => ({
...item,
postage: this.calcPostage(item.postage)
}));
},
computedEditable() {
return this.expressList && this.expressList.length >= 2 && this.editable;
},
currentOption() {
for (let i = 0; i < this.computedList.length; i++) {
if (this.computedList[i].express_type === this.value) {
return this.computedList[i];
}
}
return {};
}
},
methods: {
onSelectExpressWay(item, index) {
this.showActionsheet = false;
this.$emit('input', item.express_type);
this.$emit('change', item, index);
},
calcPostage(postage) {
return postage === 0 ? '免运费' : '¥' + (postage / 100).toFixed(2);
}
}
};
</script>

View File

@ -10,37 +10,34 @@ import CellSwipe from './cell-swipe';
import Checkbox from './checkbox';
import CheckboxGroup from './checkbox-group';
import Col from './col';
import CouponCell from './coupon-cell';
import CouponList from './coupon-list';
import DatetimePicker from './datetime-picker';
import DeepSelect from './deep-select';
import Dialog from './dialog';
import ExpressWay from './express-way';
import Field from './field';
import GoodsAction from './goods-action';
import GoodsActionBigBtn from './goods-action-big-btn';
import GoodsActionMiniBtn from './goods-action-mini-btn';
import Icon from './icon';
import ImagePreview from './image-preview';
import InvalidGoods from './invalid-goods';
import Lazyload from './lazyload';
import Loading from './loading';
import NavBar from './nav-bar';
import NoticeBar from './notice-bar';
import OrderCoupon from './order-coupon';
import OrderCouponList from './order-coupon-list';
import OrderGoods from './order-goods';
import Panel from './panel';
import PayOrder from './pay-order';
import Picker from './picker';
import Popup from './popup';
import Progress from './progress';
import PullRefresh from './pull-refresh';
import Quantity from './quantity';
import Radio from './radio';
import RadioGroup from './radio-group';
import Row from './row';
import Search from './search';
import Sku from './sku';
import Step from './step';
import Stepper from './stepper';
import Steps from './steps';
import SubmitBar from './submit-bar';
import Swipe from './swipe';
import SwipeItem from './swipe-item';
import Switch from './switch';
@ -49,6 +46,7 @@ import Tab from './tab';
import Tabs from './tabs';
import Tag from './tag';
import Toast from './toast';
import TreeSelect from './tree-select';
import Uploader from './uploader';
import Waterfall from './waterfall';
@ -66,34 +64,31 @@ const components = [
Checkbox,
CheckboxGroup,
Col,
CouponCell,
CouponList,
DatetimePicker,
DeepSelect,
ExpressWay,
Field,
GoodsAction,
GoodsActionBigBtn,
GoodsActionMiniBtn,
Icon,
InvalidGoods,
Loading,
NavBar,
NoticeBar,
OrderCoupon,
OrderCouponList,
OrderGoods,
Panel,
PayOrder,
Picker,
Popup,
Progress,
PullRefresh,
Quantity,
Radio,
RadioGroup,
Row,
Search,
Sku,
Step,
Stepper,
Steps,
SubmitBar,
Swipe,
SwipeItem,
Switch,
@ -101,6 +96,7 @@ const components = [
Tab,
Tabs,
Tag,
TreeSelect,
Uploader
];
@ -132,37 +128,34 @@ export {
Checkbox,
CheckboxGroup,
Col,
CouponCell,
CouponList,
DatetimePicker,
DeepSelect,
Dialog,
ExpressWay,
Field,
GoodsAction,
GoodsActionBigBtn,
GoodsActionMiniBtn,
Icon,
ImagePreview,
InvalidGoods,
Lazyload,
Loading,
NavBar,
NoticeBar,
OrderCoupon,
OrderCouponList,
OrderGoods,
Panel,
PayOrder,
Picker,
Popup,
Progress,
PullRefresh,
Quantity,
Radio,
RadioGroup,
Row,
Search,
Sku,
Step,
Stepper,
Steps,
SubmitBar,
Swipe,
SwipeItem,
Switch,
@ -171,6 +164,7 @@ export {
Tabs,
Tag,
Toast,
TreeSelect,
Uploader,
Waterfall
};

View File

@ -1,30 +0,0 @@
<template>
<div class="van-invalid-goods-card">
<div class="van-invalid-goods__thumb">
<img :src="item.img_url" />
<div class="van-invalid-goods-card__flag">失效</div>
</div>
<div class="van-invalid-goods-card__content">
<div class="van-invalid-goods-card__row">
<h4 class="van-invalid-goods-card__title">{{ item.title }}</h4>
<span class="van-invalid-goods-card__price">¥{{ item.price }}</span>
</div>
<div class="van-invalid-goods-card__row">
<div class="van-invalid-goods-card__sku">{{ item.sku }}</div>
<span class="van-invalid-goods-card__num">x{{ item.num }}</span>
</div>
<div class="van-invalid-goods-card__desc">{{ item.unavailable_desc }}</div>
</div>
</div>
</template>
<script>
export default {
name: 'van-invalid-goods-card',
props: {
item: Object
}
};
</script>

View File

@ -1,78 +0,0 @@
<template>
<div>
<div class="van-invalid-goods" @click="showDetail = true">
<h3 class="van-invalid-goods__title">{{ title }}</h3>
<van-cell-group class="van-invalid-goods__container">
<div class="van-invalid-goods__gallery">
<div v-for="item in formattedGoods" :key="item.sku_id" class="van-invalid-goods__thumb">
<img :src="item.img_url" />
</div>
</div>
<div class="van-invalid-goods__count">
<span>{{ formattedGoods.length }}</span>
<van-icon name="arrow" />
</div>
</van-cell-group>
</div>
<van-actionsheet v-model="showDetail" :title="actionsheetTitle">
<div class="van-invalid-goods__list">
<van-invalid-goods-card v-for="item in formattedGoods" :key="item.sku_id" :item="item" />
</div>
</van-actionsheet>
</div>
</template>
<script>
import Card from './Card';
import Icon from '../icon';
import CellGroup from '../cell-group';
import Actionsheet from '../actionsheet';
export default {
name: 'van-invalid-goods',
components: {
[Card.name]: Card,
[Icon.name]: Icon,
[CellGroup.name]: CellGroup,
[Actionsheet.name]: Actionsheet
},
props: {
goods: {
type: Array,
required: true
},
title: {
type: String,
default: '以下商品无法一起购买,点击查看原因'
},
actionsheetTitle: {
type: String,
default: '以下商品无法一起下单'
}
},
data() {
return {
showDetail: false
};
},
methods: {
getSkuStr(arr) {
return arr.filter(item => item.v).map(item => item.v).join(', ');
}
},
computed: {
formattedGoods() {
return this.goods.map(item => ({
...item,
price: parseFloat(item.price / 100, 10).toFixed(2),
sku: this.getSkuStr(item.sku)
}));
}
}
};
</script>

View File

@ -0,0 +1,38 @@
<template>
<div :class="['van-nav-bar van-hairline--top-bottom', { 'van-nav-bar--fixed': fixed }]">
<div class="van-nav-bar__left" @click="$emit('clickLeft')">
<slot name="left">
<van-icon v-if="leftArrow" class="van-nav-bar__arrow" name="arrow" />
<span v-if="leftText" v-text="leftText" class="van-nav-bar__text" />
</slot>
</div>
<div class="van-nav-bar__title">
<slot name="title">{{ title }}</slot>
</div>
<div class="van-nav-bar__right" @click="$emit('clickRight')">
<slot name="right">
<span v-if="rightText" v-text="rightText" class="van-nav-bar__text" />
</slot>
</div>
</div>
</template>
<script>
import Icon from '../icon';
export default {
name: 'van-nav-bar',
components: {
[Icon.name]: Icon
},
props: {
title: String,
leftText: String,
rightText: String,
leftArrow: Boolean,
fixed: Boolean
}
};
</script>

View File

@ -1,102 +0,0 @@
<template>
<div class="van-order-goods-card van-hairline">
<van-card>
<div slot="thumb">
<img :src="data.img_url" />
<span v-if="data.is_present" class="van-order-goods-card__present"></span>
</div>
<div class="van-card__row" slot="title">
<h4 class="van-card__title">{{ data.title }}</h4>
<span class="van-card__price">{{ price }}</span>
</div>
<template slot="desc">
<div class="van-card__row">
<p class="van-card__desc">{{ desc }}</p>
<span class="van-card__num">x {{ data.num }}</span>
</div>
<div class="van-card__row">
<div class="van-order-goods-card__tags">
<span v-if="data.is_presale" class="van-order-goods-card__tag-green">预售</span>
<span v-if="data.is_period_buy" class="van-order-goods-card__tag-red">周期购</span>
</div>
<van-button
class="van-order-goods-card__message-button"
v-if="hasMessage"
@click="onClickMessageButton"
>
查看留言
</van-button>
</div>
</template>
</van-card>
<van-cell class="van-order-goods-card__delivery van-hairline--top" v-if="data.show_delivery_time" title="发货时间" :value="data.delivery_time" />
<van-popup v-if="hasMessage" class="van-order-goods-card__message" v-model="showMessage" position="right">
<h2>备注信息</h2>
<ul>
<li v-for="(value, key) in data.message" class="van-hairline">
<label>{{ key }}</label>
<a v-if="isURL(value)" :href="value">
<img :src="value" />
</a>
<p v-else>{{ value }}</p>
</li>
</ul>
<div class="van-order-goods-card__button">
<van-button size="large" @click="showMessage = false">查看订单详情</van-button>
</div>
</van-popup>
</div>
</template>
<script>
import Card from '../card';
import Cell from '../cell';
import Button from '../button';
import Popup from '../popup';
import { getTotalPrice } from './utils';
export default {
name: 'van-order-goods-card',
components: {
[Card.name]: Card,
[Cell.name]: Cell,
[Popup.name]: Popup,
[Button.name]: Button
},
props: {
data: {
type: Object,
required: true
}
},
data() {
return {
showMessage: false
};
},
computed: {
price() {
return getTotalPrice(this.data.pay_price, this.data.points_price);
},
desc() {
return this.data.sku ? this.data.sku.filter(item => item.v).map(item => item.v).join(', ') : '';
},
hasMessage() {
return this.data.message && Object.keys(this.data.message).length;
}
},
methods: {
onClickMessageButton() {
this.showMessage = true;
},
isURL(value) {
return /^\s*http(s)*:\/\/.+/.test(value);
}
}
};
</script>

View File

@ -1,25 +0,0 @@
<template>
<div class="van-order-goods-empty van-hairline--top">
<img :src="icon" />
<p>{{ message }}</p>
<van-button @click="$emit('clickEmptyButton')">{{ buttonText }}</van-button>
</div>
</template>
<script>
import Button from '../button';
export default {
name: 'van-order-goods-empty',
components: {
[Button.name]: Button
},
props: {
icon: String,
message: String,
buttonText: String
}
};
</script>

View File

@ -1,26 +0,0 @@
<template>
<div class="van-order-goods-header">
<van-icon :name="icon" />
<a :href="link">{{ title }}</a>
<img v-if="badge" :src="badge" />
</div>
</template>
<script>
import Icon from '../icon';
export default {
name: 'van-order-goods-header',
components: {
[Icon.name]: Icon
},
props: {
title: String,
icon: String,
link: String,
badge: String
}
};
</script>

View File

@ -1,50 +0,0 @@
<template>
<van-cell class="van-order-goods-message" title="买家留言:">
<textarea
v-if="editable"
:value="message"
:class="{ 'van-order-goods-message-focused': textareaFocused }"
placeholder="点击给商家留言"
@focus="textareaFocused = true"
@blur="textareaFocused = false"
@input="onChange"
/>
<p v-else>{{ message }}</p>
</van-cell>
</template>
<script>
import Cell from '../cell';
export default {
name: 'van-order-goods-message',
components: {
[Cell.name]: Cell
},
props: {
message: String,
editable: Boolean
},
data() {
return {
textareaFocused: false
};
},
methods: {
onChange(event) {
this.$emit('change', event.target.value);
}
},
created() {
// ""
if (!this.editable && !this.message) {
this.$emit('change', '无');
}
}
};
</script>

View File

@ -1,32 +0,0 @@
<template>
<van-cell
class="van-order-goods-price"
title="合计"
:value="totalPrice"
/>
</template>
<script>
import Cell from '../cell';
import { getTotalPrice } from './utils';
export default {
name: 'van-order-goods-price',
components: {
[Cell.name]: Cell
},
props: {
price: Number,
points: Number,
isPoints: Boolean
},
computed: {
totalPrice() {
return getTotalPrice(this.price, this.points, this.isPoints);
}
}
};
</script>

View File

@ -1,114 +0,0 @@
<template>
<van-cell-group class="van-order-goods">
<van-order-goods-header
:title="shopName"
:link="shopLink"
:icon="headerIcon"
:badge="headerBadge"
/>
<slot name="top"></slot>
<van-order-goods-empty
v-if="isEmpty"
:icon="emptyIcon"
:message="emptyMessage"
:button-text="emptyButtonText"
@clickEmptyButton="$emit('clickEmptyButton')"
/>
<div class="van-order-goods-list">
<van-order-goods-card
v-for="item in itemList"
:data="item"
:express-way="expressWay"
:key="item.title + item.img_url"
/>
</div>
<slot></slot>
<template v-if="!isEmpty">
<van-order-goods-message v-if="showMessage" :message="message" :editable="messageEditable" @change="onMessageChange" />
<van-order-goods-price v-if="showTotalPrice" :price="price" :points="points" />
</template>
<slot name="bottom"></slot>
</van-cell-group>
</template>
<script>
import Header from './Header';
import Empty from './Empty';
import Message from './Message';
import Price from './Price';
import Card from './Card';
import CellGroup from '../cell-group';
export default {
name: 'van-order-goods',
components: {
[Empty.name]: Empty,
[Header.name]: Header,
[Message.name]: Message,
[Price.name]: Price,
[Card.name]: Card,
[CellGroup.name]: CellGroup
},
model: {
prop: 'message'
},
props: {
shopName: String,
shopLink: String,
message: String,
price: Number,
points: Number,
expressWay: String,
headerBadge: String,
headerIcon: {
type: String,
default: 'shop'
},
emptyIcon: {
type: String,
default: '//b.yzcdn.cn/v2/image/wap/trade/new_order/empty@2x.png'
},
emptyMessage: {
type: String,
default: '当前没有可购买的商品,请重新选择'
},
emptyButtonText: {
type: String,
default: '返回重新选择'
},
showMessage: {
type: Boolean,
default: true
},
showTotalPrice: {
type: Boolean,
default: true
},
messageEditable: {
type: Boolean,
default: true
},
itemList: {
type: Array,
default() {
return [];
}
}
},
computed: {
isEmpty() {
return this.itemList.length === 0;
}
},
methods: {
onMessageChange(message) {
this.$emit('input', message);
}
}
};
</script>

View File

@ -1,13 +0,0 @@
/**
* 拼接商品价格金额和积分
*/
export function getTotalPrice(price, points) {
const arr = [];
if (points) {
arr.push(points + '积分');
}
if (price) {
arr.push('¥' + (price / 100).toFixed(2));
}
return arr.join(' + ');
}

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

@ -1,14 +1,14 @@
<template>
<div class="van-pay-order">
<div class="van-pay-order__tip" v-show="tip || $slots.tip">
<slot name="tip">{{ tip }}</slot>
<div class="van-submit-bar">
<div class="van-submit-bar__tip" v-show="tip || $slots.tip">
{{ tip }}<slot name="tip"></slot>
</div>
<div class="van-pay-order__bar">
<div class="van-pay-order__price">
<div class="van-submit-bar__bar">
<div class="van-submit-bar__price">
<template v-if="hasPrice">
<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>
<span class="van-submit-bar__price-text">合计</span>
<span class="van-submit-bar__price-interger">¥{{ priceInterger }}.</span>
<span class="van-submit-bar__price-decimal">{{ priceDecimal }}</span>
</template>
</div>
<van-button :type="buttonType" :disabled="disabled" :loading="loading" @click="onSubmit">
@ -22,7 +22,7 @@
import Button from '../button';
export default {
name: 'van-pay-order',
name: 'van-submit-bar',
components: {
[Button.name]: Button

View File

@ -1,26 +1,26 @@
<template>
<div class="van-deep-select" :style="{ height: mainHeight + 'px' }">
<div class="van-deep-select__nav">
<div class="van-tree-select" :style="{ height: mainHeight + 'px' }">
<div class="van-tree-select__nav">
<div
v-for="(item, index) in items"
class="van-deep-select__nitem"
:class="{ 'van-deep-select__nitem--active': mainActiveIndex === index }"
@click="onNavClick(index)">
class="van-tree-select__nitem"
:class="{ 'van-tree-select__nitem--active': mainActiveIndex === index }"
@click="$emit('navclick', index)">
{{ item.text }}
</div>
</div>
<div class="van-deep-select__content" :style="{ height: itemHeight + 'px' }">
<div class="van-tree-select__content" :style="{ height: itemHeight + 'px' }">
<div
v-for="item in subItems"
:key="item.id"
class="van-deep-select__item"
:class="{ 'van-deep-select__item--active': activeId === item.id }"
class="van-tree-select__item"
:class="{ 'van-tree-select__item--active': activeId === item.id }"
@click="onItemSelect(item)">
{{ item.text }}
<van-icon
v-if="activeId === item.id"
name="success"
class="van-deep-select__selected"
class="van-tree-select__selected"
></van-icon>
</div>
</div>
@ -31,7 +31,7 @@
import Icon from 'packages/icon';
export default {
name: 'van-deep-select',
name: 'van-tree-select',
components: {
'van-icon': Icon
@ -40,9 +40,7 @@ export default {
props: {
items: {
type: Array,
default () {
return [];
}
default: () => []
},
mainActiveIndex: {
type: Number,
@ -73,12 +71,8 @@ export default {
},
methods: {
onNavClick(index) {
this.$emit('navclick', index);
},
onItemSelect(data) {
const exportData = Object.assign({}, data);
this.$emit('itemclick', exportData);
this.$emit('itemclick', { ...data });
}
}
};

View File

@ -1,7 +1,7 @@
@import './common/var.css';
@import "./mixins/ellipsis.css";
.van-order-coupon {
.van-coupon {
&-list {
height: 100%;
background-color: $background-color;
@ -57,7 +57,7 @@
}
}
.van-order-coupon-card + h3 {
.van-coupon-item + h3 {
margin-top: 30px;
}
}
@ -74,7 +74,7 @@
}
}
&-coupon {
&-item {
display: flex;
height: 100px;
margin: 0 15px 10px;
@ -176,11 +176,11 @@
}
&--disabled {
.van-order-coupon-coupon__lines {
.van-coupon-item__lines {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAADICAMAAAC3WLNTAAAAWlBMVEUAAACqrremq7Oqv7+mq7Wqqr+rsLeprreqsrmqrralq7SkqbKrsbikqLGqwNWqrrmrr7mkqbGrsbijqLGnq7SssrimrLKlqrOnrLWprraqr7ekqbKrsLijqLGfTYl9AAAAF3RSTlMAN5oMQgya5kJC5uaSkgZC8/PV1b0rK6hQU+kAAASjSURBVFjDfZlJduMwDESZntJDeh5sUdb9r9kuA+AXA0iIIi/8X6FYALNJU/19+fWj3/pNT1V35NvLratgMvTtjxH+1NBLt7rLHbb7OwhVrSUhKQhz7z1Dv6xZoLWnH70vg5ESINDedkg5BrR0yrGs9Pbpw21SqxNvH593YsN+30OibhwvaQXUPgghVH1m6EkAXK30VllB+UeCMG7OmCPtlk5exN6TcWsRv0UE/aG0GIKxMsycfB9j6QgZwn7FgO/AYhSFq+7Q4hBgyMT9kJKkkhJiriTEuoKACereTw+Y98LTsDVvKdenDWAW6gh1lNwTGHvjEGGhRre+U3J0iKGGknl7zeCJjoBCDPQBBxXhY94WwlYFuXLQTfW979LKYKzvECKH3aLGRSCFnnPwK7UPi8VZ7IRAGH+9X9w7iv0a3GvjZG+F8Y8LRRS0fMQ0hUn0o2ws1wEB7tJqV4iEDKVlgZo5bDWYPQWiVzNmNCX2CMo9XSutziEFoTRjRNqkAwBBqBGBvSpMpEVwrXLgr9Gidi511FaQSZVASO2VkJqxRQPefw3GbX2syqdnqdEy2bd7F77qWRvU3ggp09LDvUMmu/crJVN+wlRA9CrG4+0eadmTteLeScW0/De3+zSEljIpD3Mx53WoGssbfQfgrwm6Un5EgAJCL0MAQ2r4AkoYzoBgBnbuiREilSGLw/YLpUuSChBjKAGltIBSzxDKUOpVQYbEx27ABTYiEOurUjvSi6V7V0ihxb3LqbNfXARqRvdXqmb8fgyI8eSNqNst834l41mNe1f1G38EHzE9w8ycZW5juVzEwCHl7S5CqJJrd0Sci9VUM8CcJ843qwnBVFUGCamJBU+OGVsEKsiYE18egQllJSLA1ZF3Nx6uyoYonRwRJbBM+oANtY6pbFU+iwBMp/R7x/dZa6yvGELVZ4aeRliEn6C3QlDzvgnyIvS6HYWpZJxQzRQUEYC5fTDCpFjleLf3jGWvhTG2oKKoBHEA2tZK1gxPpdC8XzXELosBOsIeYDsEEMpKOXugGjG1MyUW9VgJBqWC88cGfJKCgazKETiW7jhOFeubigvNRTjbGIPeFwRJAB1T3LvTwviJFhGshxRhnjl/jGVd0Sk9rUKoGroj4s7EtE/x9aqnhqQRptYzTysqJ578dQIZ475OIvATnhlfcVVjzZFwFXCthNipUo0xYHpVjK3KFxcTk8FYujuB0Hq0vkgJ0WeGnggrjYcrRRCRfwENBk+53SbEQUxl43ZAY48jwDvhz2GqAMuxbPcfPbF/Q4gBb5teoQMFtN0rkE3AiAqw6euBccRaaRMK5kccSsIQYmeMNUiAYU5iC08BGAGAkCBvuEZa+Wq0Gclh6SWl4X1Ogt1pmwMg2/6MYvCkj30/5mgDXi1PDrmNQxpoqxJCSCE3lk4KKdRLjDvWdwPAfQQ6LgJHnPK0CPxK2fnQA1MBCaDZ/oS0A4v9oty4MajNgVoEG7UOMaIgTJy7LZzHWGBWA+FswBTctMsZYr+AfpbAHFb7XQiZScy3rxliFfzd/h06wlY7kJp86d+FGTEhlO4UWgU6Bvzv6++fmWGE/wHKk5MgoCYAjwAAAABJRU5ErkJggg==');
}
.van-order-coupon-coupon__gradient {
.van-coupon-item__gradient {
background-image: linear-gradient(45deg, #a4a9b2, #b7bcc3);
}
}

View File

@ -1,60 +0,0 @@
@import './common/var.css';
.van-express-way {
padding: 0;
&__fee,
&__type {
color: $gray-darker;
line-height: 1.5;
}
&__fee {
font-size: 14px;
}
&__type {
font-size: 12px;
}
.van-actionsheet__content {
max-height: 290px;
overflow-y: auto;
}
&-option {
position: relative;
padding: 14px 15px 14px 0;
.van-radio {
top: 50%;
left: 0;
margin-top: -11px;
position: absolute;
}
&__content {
padding-left: 30px;
p {
color: $gray-dark;
font-size: 12px;
line-height: 16px;
}
}
&__title {
span {
vertical-align: middle;
&:first-child {
margin-right: 5px;
}
}
}
&__warn {
color: $yellow;
}
}
}

View File

@ -12,10 +12,11 @@
@import './badge.css';
@import './button.css';
@import './cell.css';
@import './cell-swipe.css';
@import './card.css';
@import './icon.css';
@import './loading.css';
@import './nav-bar.css';
@import './notice-bar.css';
@import './popup.css';
@import './search.css';
@import './panel.css';
@ -23,7 +24,7 @@
@import './tag.css';
@import './tab.css';
@import './image-preview.css';
@import './quantity.css';
@import './stepper.css';
@import './progress.css';
@import './swipe.css';
@ -41,14 +42,13 @@
@import './pull-refresh.css';
@import './toast.css';
/* business components */
@import './deep-select.css';
@import './express-way.css';
@import './goods-action.css';
@import './invalid-goods.css';
@import './notice-bar.css';
@import './order-coupon.css';
@import './order-goods.css';
@import './pay-order.css';
/* high order components */
@import './cell-swipe.css';
@import './switch-cell.css';
@import './tree-select.css';
/* business components */
@import './coupon-list.css';
@import './goods-action.css';
@import './submit-bar.css';
@import './sku.css';

View File

@ -1,122 +0,0 @@
@import './common/var.css';
@import "./mixins/ellipsis.css";
$van-invalid-goods-photo-size: 90px;
.van {
&-invalid-goods {
margin: 10px 0;
&__title {
color: $gray-dark;
font-size: 12px;
text-align: center;
margin-bottom: 10px;
}
&__container {
padding: 5px 10px;
}
&__gallery {
overflow: hidden;
height: $van-invalid-goods-photo-size;
}
&__thumb {
float: left;
display: flex;
height: 100%;
position: relative;
margin-right: 5px;
align-items: center;
justify-content: center;
img {
max-width: $van-invalid-goods-photo-size;
max-height: $van-invalid-goods-photo-size;
}
}
&__count {
position: absolute;
top: 0;
right: 0;
width: 80px;
color: $gray-darker;
font-size: 14px;
padding-right: 8px;
line-height: calc($van-invalid-goods-photo-size + 10px);
background-color: $white;
text-align: right;
span {
margin-right: 6px;
vertical-align: middle;
}
}
&__list {
max-height: 400px;
overflow-y: scroll;
}
}
&-invalid-goods-card {
color: $gray-dark;
margin: 10px 0;
padding: 5px 10px;
background-color: #fafafa;
height: $van-invalid-goods-photo-size;
&__flag {
position: absolute;
left: 0;
top: 70px;
width: $van-invalid-goods-photo-size;
color: $white;
font-size: 12px;
line-height: 20px;
text-align: center;
background-color: rgba(0,0,0,.6);
}
&__content {
width: 100%;
padding-left: 100px;
box-sizing: border-box;
}
&__row {
display: flex;
line-height: 20px;
}
&__title,
&__sku {
flex: 1;
@mixin multi-ellipsis 2;
}
&__title,
&__price {
font-size: 14px;
}
&__num,
&__sku {
font-size: 12px;
}
&__desc {
color: $orange;
font-size: 12px;
margin-top: 5px;
}
}
.van-icon-arrow {
color: $gray-darker;
font-size: 10px;
}
}

View File

@ -0,0 +1,60 @@
@import './common/var.css';
.van-nav-bar {
height: 46px;
position: relative;
user-select: none;
text-align: center;
line-height: 46px;
background-color: #fff;
.van-icon {
color: $blue;
}
&__arrow {
transform: rotate(180deg);
+ .van-nav-bar__text {
margin-left: -20px;
padding-left: 25px;
}
}
&--fixed {
top: 0;
left: 0;
width: 100%;
position: fixed;
}
&__title {
font-size: 16px;
}
&__left,
&__right {
bottom: 0;
font-size: 14px;
position: absolute;
}
&__left {
left: 15px;
}
&__right {
right: 15px;
}
&__text {
color: $blue;
margin: 0 -15px;
padding: 0 15px;
display: inline-block;
&:active {
background-color: $active-color;
}
}
}

View File

@ -1,205 +0,0 @@
@import './common/var.css';
.van-order-goods {
background-color: $white;
&-card {
margin-left: -15px;
background-color: #fafafa;
&:not(:first-child) {
&::after {
border-top-width: 1px;
}
}
&__tags {
flex: 1;
}
&__tag-green,
&__tag-red {
font-size: 10px;
padding: 3px 5px;
margin-right: 5px;
border-radius: 2px;
display: inline-block;
}
&__tag-green {
color: $white;
background-color: $green-wx;
}
&__tag-red {
color: $gray;
padding: 5px 8px;
border: 1px solid $gray;
}
&__delivery {
padding-left: 15px;
background-color: transparent;
.van-cell__value {
color: $gray-darker;
}
}
&__present {
top: 0;
left: 3px;
width: 18px;
height: 36px;
position: absolute;
background: url("https://b.yzcdn.cn/v2/image/wap/trade/confirm/present@2x.png") no-repeat;
background-size: 18px 36px;
}
.van-button&__message-button {
height: 24px;
padding: 0 5px;
font-size: 10px;
line-height: 22px;
}
&__button {
padding: 20px 15px 0;
.van-button {
height: 40px;
line-height: 38px;
}
}
&__message {
width: 100%;
height: 100%;
background-color: $background-color;
h2 {
color: $gray-dark;
font-size: 12px;
line-height: 18px;
padding: 5px 0 5px 10px;
}
ul {
background-color: $white;
}
p,
a,
label {
font-size: 14px;
padding: 14px 0;
line-height: 20px;
vertical-align: top;
display: inline-block;
}
label {
color: #c9c9c9;
min-width: 90px;
}
li {
display: flex;
padding: 0 10px;
&:not(:last-child)::after {
border-bottom-width: 1px;
}
img {
width: 70px;
height: 70px;
}
}
}
}
&-empty {
margin-left: -15px;
text-align: center;
p {
color: $gray-dark;
padding: 0 10px;
font-size: 14px;
line-height: 20px;
}
img {
width: 80px;
height: 84px;
padding: 15px 0;
}
.van-button {
height: 41px;
margin: 15px 0;
padding: 0 10px;
line-height: 39px;
border-color: $gray-light;
}
}
&-header {
line-height: 50px;
a,
img,
.van-icon {
vertical-align: middle;
}
.van-icon {
font-size: 18px;
margin-right: 5px;
}
a {
color: $text-color;
font-size: 14px;
}
img {
height: 14px;
margin-left: 5px;
}
}
&-message {
textarea {
color: $gray-darker;
padding: 0;
width: 100%;
height: 22px;
border: none;
resize: none;
display: block;
font-size: 14px;
line-height: 22px;
transition: height .3s ease-in-out;
}
textarea&-focused {
height: 48px;
}
p {
color: $gray-darker;
text-align: left;
}
.van-cell__title {
width: 75px;
}
}
&-price {
.van-cell__value {
color: $red;
}
}
}

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

@ -1,6 +1,6 @@
@import './common/var.css';
.van-pay-order {
.van-submit-bar {
left: 0;
bottom: 0;
width: 100%;

View File

@ -2,7 +2,7 @@
@import "./mixins/clearfix.css";
@import './common/var.css';
.van-deep-select {
.van-tree-select {
user-select: none;
position: relative;
@mixin clearfix;

View File

@ -1,5 +1,5 @@
import OrderCoupon from 'packages/order-coupon';
import OrderCouponList from 'packages/order-coupon-list';
import CouponCell from 'packages/coupon-cell';
import CouponList from 'packages/coupon-list';
import { mount } from 'avoriaz';
import { DOMChecker } from '../utils';
@ -42,14 +42,14 @@ const disabledDiscountCoupon = {
reason: '未满足使用门槛'
};
describe('OrderCoupon', () => {
describe('CouponCell', () => {
let wrapper;
afterEach(() => {
wrapper && wrapper.destroy();
});
it('no coupon', () => {
wrapper = mount(OrderCoupon, {});
wrapper = mount(CouponCell, {});
DOMChecker(wrapper, {
text: {
@ -59,7 +59,7 @@ describe('OrderCoupon', () => {
});
it('has two coupon', () => {
wrapper = mount(OrderCoupon, {
wrapper = mount(CouponCell, {
propsData: {
coupons: [coupon, discountCoupon]
}
@ -73,7 +73,7 @@ describe('OrderCoupon', () => {
});
it('select first coupon', () => {
wrapper = mount(OrderCoupon, {
wrapper = mount(CouponCell, {
propsData: {
chosenCoupon: 0,
coupons: [coupon, discountCoupon]
@ -92,7 +92,7 @@ describe('OrderCoupon', () => {
});
it('not editable', () => {
wrapper = mount(OrderCoupon, {
wrapper = mount(CouponCell, {
propsData: {
chosenCoupon: 0,
coupons: [coupon, discountCoupon],
@ -112,14 +112,14 @@ describe('OrderCoupon', () => {
});
});
describe('OrderCouponList', () => {
describe('CouponList', () => {
let wrapper;
afterEach(() => {
wrapper && wrapper.destroy();
});
it('no coupon', () => {
wrapper = mount(OrderCouponList, {
wrapper = mount(CouponList, {
propsData: {
chosenCoupon: -1
}
@ -127,15 +127,15 @@ describe('OrderCouponList', () => {
DOMChecker(wrapper, {
count: {
'.van-order-coupon-coupon': 0,
'.van-order-coupon-coupon--disabled': 0,
'.van-order-coupon-list__list h3': 0
'.van-coupon-item': 0,
'.van-coupon-item--disabled': 0,
'.van-coupon-list__list h3': 0
}
});
});
it('has two coupon', () => {
wrapper = mount(OrderCouponList, {
wrapper = mount(CouponList, {
propsData: {
chosenCoupon: -1,
coupons: [coupon, discountCoupon],
@ -144,15 +144,15 @@ describe('OrderCouponList', () => {
});
DOMChecker(wrapper, {
count: {
'.van-order-coupon-coupon': 4,
'.van-order-coupon-coupon--disabled': 2,
'.van-order-coupon-list__list h3': 1
'.van-coupon-item': 4,
'.van-coupon-item--disabled': 2,
'.van-coupon-list__list h3': 1
}
});
});
it('switch to first coupon', (done) => {
wrapper = mount(OrderCouponList, {
wrapper = mount(CouponList, {
attachToDocument: true,
propsData: {
show: true,
@ -168,8 +168,8 @@ describe('OrderCouponList', () => {
// 弹出 popup
setTimeout(() => {
expect(wrapper.find('.van-order-coupon-list')[0].hasStyle('display', 'none')).to.equal(false);
wrapper.find('.van-order-coupon-coupon')[0].trigger('click');
expect(wrapper.find('.van-coupon-list')[0].hasStyle('display', 'none')).to.equal(false);
wrapper.find('.van-coupon-item')[0].trigger('click');
setTimeout(() => {
expect(wrapper.vm.chosenCoupon).to.equal(0);
@ -179,7 +179,7 @@ describe('OrderCouponList', () => {
});
it('cancel select coupon', (done) => {
wrapper = mount(OrderCouponList, {
wrapper = mount(CouponList, {
attachToDocument: true,
propsData: {
show: false,
@ -198,17 +198,17 @@ describe('OrderCouponList', () => {
});
setTimeout(() => {
wrapper.find('.van-order-coupon-list__close')[0].trigger('click');
wrapper.find('.van-coupon-list__close')[0].trigger('click');
setTimeout(() => {
expect(wrapper.vm.chosenCoupon).to.equal(-1);
expect(wrapper.find('.van-order-coupon-list')[0].hasStyle('display', 'none')).to.equal(true);
expect(wrapper.find('.van-coupon-list')[0].hasStyle('display', 'none')).to.equal(true);
done();
}, 500);
}, 500);
});
it('denominations format', () => {
wrapper = mount(OrderCouponList, {
wrapper = mount(CouponList, {
attachToDocument: true,
propsData: {
coupons: [coupon, {
@ -227,15 +227,15 @@ describe('OrderCouponList', () => {
}
});
expect(wrapper.find('.van-order-coupon-coupon__gradient h2')[0].text()).to.equal('¥ 1.5');
expect(wrapper.find('.van-order-coupon-coupon__gradient h2')[1].text()).to.equal('¥ 0.1');
expect(wrapper.find('.van-order-coupon-coupon__gradient h2')[2].text()).to.equal('¥ 1');
expect(wrapper.find('.van-order-coupon-coupon__gradient h2')[3].text()).to.equal('¥ 1.35');
expect(wrapper.find('.van-order-coupon-coupon__gradient h2')[4].text()).to.equal('');
expect(wrapper.find('.van-coupon-item__gradient h2')[0].text()).to.equal('¥ 1.5');
expect(wrapper.find('.van-coupon-item__gradient h2')[1].text()).to.equal('¥ 0.1');
expect(wrapper.find('.van-coupon-item__gradient h2')[2].text()).to.equal('¥ 1');
expect(wrapper.find('.van-coupon-item__gradient h2')[3].text()).to.equal('¥ 1.35');
expect(wrapper.find('.van-coupon-item__gradient h2')[4].text()).to.equal('');
});
it('discount format', () => {
wrapper = mount(OrderCouponList, {
wrapper = mount(CouponList, {
attachToDocument: true,
propsData: {
coupons: [discountCoupon, {
@ -248,13 +248,13 @@ describe('OrderCouponList', () => {
}
});
expect(wrapper.find('.van-order-coupon-coupon__gradient h2')[0].text()).to.equal('8.8折');
expect(wrapper.find('.van-order-coupon-coupon__gradient h2')[1].text()).to.equal('1折');
expect(wrapper.find('.van-order-coupon-coupon__gradient h2')[2].text()).to.equal('');
expect(wrapper.find('.van-coupon-item__gradient h2')[0].text()).to.equal('8.8折');
expect(wrapper.find('.van-coupon-item__gradient h2')[1].text()).to.equal('1折');
expect(wrapper.find('.van-coupon-item__gradient h2')[2].text()).to.equal('');
});
it('add coupon', (done) => {
wrapper = mount(OrderCouponList, {
wrapper = mount(CouponList, {
attachToDocument: true,
propsData: {
show: true,
@ -282,7 +282,7 @@ describe('OrderCouponList', () => {
wrapper.find('.van-field__control')[0].trigger('input');
setTimeout(() => {
wrapper.find('.van-order-coupon-list__exchange')[0].trigger('click');
wrapper.find('.van-coupon-list__exchange')[0].trigger('click');
DOMChecker(wrapper, {
count: {
'.van-button--disabled': 0
@ -290,12 +290,12 @@ describe('OrderCouponList', () => {
});
setTimeout(() => {
expect(wrapper.find('.van-order-coupon-list')[0].hasStyle('display', 'none')).to.equal(false);
expect(wrapper.find('.van-coupon-list')[0].hasStyle('display', 'none')).to.equal(false);
DOMChecker(wrapper, {
count: {
'.van-button--disabled': 1,
'.van-order-coupon-coupon': 6,
'.van-order-coupon-coupon--disabled': 2
'.van-coupon-item': 6,
'.van-coupon-item--disabled': 2
}
});
done();
@ -305,7 +305,7 @@ describe('OrderCouponList', () => {
});
it('displayedCouponIndex out of range', (done) => {
wrapper = mount(OrderCouponList, {
wrapper = mount(CouponList, {
propsData: {
show: true,
displayedCouponIndex: -100,

View File

@ -1,201 +0,0 @@
import ExpressWay from 'packages/express-way';
import { mount } from 'avoriaz';
import { DOMChecker } from '../utils';
const mockData = [{
'postage': 10050,
'postage_desc': '由商家门店提供配送服务, 起送价 0.01 元',
'postage_title': '同城配送',
'express_type': 1
}, {
'postage': 0,
'postage_desc': '由商家选择合作快递为您服务',
'postage_title': '快递发货',
'express_type': 2,
'postage_warn_desc': '3天后发货'
}];
describe('ExpressWay', () => {
let wrapper;
afterEach(() => {
wrapper && wrapper.destroy();
});
it('default', () => {
wrapper = mount(ExpressWay, {
attachToDocument: true,
propsData: {
value: 1,
expressList: mockData
}
});
DOMChecker(wrapper, {
text: {
'.van-cell__text': '配送方式',
'.van-express-way__fee': '¥100.50',
'.van-express-way__type': mockData[0].postage_title,
'.van-actionsheet__header h3': '配送方式',
'.van-express-way-option__title span': mockData[0].postage_title,
'.van-express-way-option__content p': mockData[0].postage_desc
},
count: {
'.van-icon-arrow': 1
},
style: {
'.van-actionsheet': {
display: 'none'
}
}
});
});
it('show actionsheet', (done) => {
wrapper = mount(ExpressWay, {
attachToDocument: true,
propsData: {
value: 1,
expressList: mockData
}
});
// 点击后弹出 actionsheet
const cells = wrapper.find('.van-cell');
cells[cells.length - 1].trigger('click');
setTimeout(() => {
expect(wrapper.find('.van-actionsheet')[0].hasStyle('display', 'none')).to.equal(false);
done();
}, 500);
});
it('change express way', (done) => {
wrapper = mount(ExpressWay, {
attachToDocument: true,
propsData: {
value: 1,
expressList: mockData
}
});
wrapper.vm.$on('input', val => {
wrapper.vm.value = val;
});
// 点击后弹出 actionsheet
const cells = wrapper.find('.van-cell');
cells[cells.length - 1].trigger('click');
// 监听 change 事件
const submitSpyFunc = sinon.spy();
wrapper.vm.$on('change', submitSpyFunc);
setTimeout(() => {
expect(wrapper.find('.van-actionsheet')[0].hasStyle('display', 'none')).to.equal(false);
const secondOption = wrapper.find('.van-express-way-option')[1];
secondOption.trigger('click');
setTimeout(() => {
expect(wrapper.find('.van-actionsheet')[0].hasStyle('display', 'none')).to.equal(true);
DOMChecker(wrapper, {
text: {
'.van-express-way__fee': '免运费',
'.van-express-way__type': mockData[1].postage_title
}
});
// 修改后触发 change 事件
expect(submitSpyFunc.calledOnce).to.be.true;
done();
}, 500);
}, 500);
});
it('cellTitle prop', () => {
wrapper = mount(ExpressWay, {
attachToDocument: true,
propsData: {
value: 1,
cellTitle: '测试标题',
expressList: mockData
}
});
DOMChecker(wrapper, {
text: {
'.van-cell__text': '测试标题'
}
});
});
it('actionsheetTitle prop', () => {
wrapper = mount(ExpressWay, {
attachToDocument: true,
propsData: {
value: 1,
actionsheetTitle: '测试标题',
expressList: mockData
}
});
DOMChecker(wrapper, {
text: {
'.van-actionsheet__header h3': '测试标题'
}
});
});
it('set editable false ', () => {
wrapper = mount(ExpressWay, {
attachToDocument: true,
propsData: {
value: 1,
editable: false,
expressList: mockData
}
});
DOMChecker(wrapper, {
count: {
'.van-icon-arrow': 0,
'.van-actionsheet': 0
}
});
});
it('not editable when only one option', () => {
wrapper = mount(ExpressWay, {
attachToDocument: true,
propsData: {
value: 1,
editable: true,
expressList: mockData.slice(0, 1)
}
});
DOMChecker(wrapper, {
count: {
'.van-icon-arrow': 0,
'.van-actionsheet': 0
}
});
});
it('unexist express type', () => {
wrapper = mount(ExpressWay, {
attachToDocument: true,
propsData: {
value: -1,
expressList: mockData
}
});
DOMChecker(wrapper, {
text: {
'.van-express-way__fee': '',
'.van-express-way__type': ''
}
});
});
});

View File

@ -1,81 +0,0 @@
import InvalidGoods from 'packages/invalid-goods/index';
import { mount } from 'avoriaz';
import { DOMChecker } from '../utils';
const mockItem = {
sku: [{ v: '商品SKU1' }, { v: '商品SKU2' }],
num: 2,
'sku_id': 123,
title: '商品名称',
price: 12200,
'unavailable_desc': '超出配送区域',
'img_url': 'https://img.yzcdn.cn/upload_files/2017/06/29/FnPSAKkEeh4FnDA09oIbmnlzWQrw.png'
};
describe('InvalidGoods', () => {
let wrapper;
afterEach(() => {
wrapper && wrapper.destroy();
});
it('default', () => {
wrapper = mount(InvalidGoods, {
attachToDocument: true,
propsData: {
goods: [mockItem, mockItem, mockItem]
}
});
DOMChecker(wrapper, {
text: {
'.van-invalid-goods__title': '以下商品无法一起购买,点击查看原因',
'.van-actionsheet__header h3': '以下商品无法一起下单',
'.van-invalid-goods-card__price': '¥122.00',
'.van-invalid-goods-card__sku': '商品SKU1, 商品SKU2',
'.van-invalid-goods-card__title': mockItem.title,
'.van-invalid-goods-card__num': 'x' + mockItem.num,
'.van-invalid-goods-card__desc': mockItem.unavailable_desc,
'.van-invalid-goods__count span': '共3件'
},
count: {
'.van-invalid-goods-card': 3,
'.van-invalid-goods__gallery img': 3
},
src: {
'.van-invalid-goods__thumb img': mockItem.img_url
}
});
});
it('title prop', () => {
wrapper = mount(InvalidGoods, {
attachToDocument: true,
propsData: {
goods: [mockItem],
title: '标题'
}
});
DOMChecker(wrapper, {
text: {
'.van-invalid-goods__title': '标题'
}
});
});
it('actionsheetTitle prop', () => {
wrapper = mount(InvalidGoods, {
attachToDocument: true,
propsData: {
goods: [mockItem],
actionsheetTitle: 'actionsheet标题'
}
});
DOMChecker(wrapper, {
text: {
'.van-actionsheet__header h3': 'actionsheet标题'
}
});
});
});

View File

@ -0,0 +1,43 @@
import NavBar from 'packages/nav-bar';
import { mount } from 'avoriaz';
import { DOMChecker } from '../utils';
describe('NavBar', () => {
let wrapper;
afterEach(() => {
wrapper && wrapper.destroy();
});
it('create a NavBar', () => {
wrapper = mount(NavBar, {
propsData: {
title: '标题',
leftText: '返回',
rightText: '按钮',
leftArrow: true
}
});
DOMChecker(wrapper, {
text: {
'.van-nav-bar__title': '标题',
'.van-nav-bar__left .van-nav-bar__text': '返回',
'.van-nav-bar__right .van-nav-bar__text': '按钮'
},
count: {
'.van-nav-bar__arrow': 1
}
});
expect(wrapper.hasClass('van-nav-bar')).to.be.true;
});
it('NavBar fixed', () => {
wrapper = mount(NavBar, {
propsData: {
fixed: true
}
});
expect(wrapper.hasClass('van-nav-bar')).to.be.true;
});
});

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');

View File

@ -1,8 +1,8 @@
import PayOrder from 'packages/pay-order';
import SubmitBar from 'packages/submit-bar';
import { mount } from 'avoriaz';
import { DOMChecker } from '../utils';
describe('PayOrder', () => {
describe('SubmitBar', () => {
let wrapper;
afterEach(() => {
wrapper && wrapper.destroy();
@ -15,22 +15,22 @@ describe('PayOrder', () => {
tip: '您的收货地址不支持同城送, 我们已为您推荐快递'
};
wrapper = mount(PayOrder, {
wrapper = mount(SubmitBar, {
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
'.van-submit-bar__price-interger': '¥30.',
'.van-submit-bar__price-decimal': '50',
'.van-submit-bar__tip': props.tip
}
});
});
it('no tip', () => {
wrapper = mount(PayOrder, {
wrapper = mount(SubmitBar, {
propsData: {
price: 3005,
buttonText: '提交订单',
@ -41,15 +41,15 @@ describe('PayOrder', () => {
DOMChecker(wrapper, {
text: {
'.van-button__text': '提交订单',
'.van-pay-order__price-interger': '¥30.',
'.van-pay-order__price-decimal': '05',
'.van-pay-order__tip': ''
'.van-submit-bar__price-interger': '¥30.',
'.van-submit-bar__price-decimal': '05',
'.van-submit-bar__tip': ''
}
});
});
it('handle submit', () => {
wrapper = mount(PayOrder, {
wrapper = mount(SubmitBar, {
propsData: {
price: 3005,
buttonText: '提交订单'
@ -65,7 +65,7 @@ describe('PayOrder', () => {
});
it('can not submit when disabled', () => {
wrapper = mount(PayOrder, {
wrapper = mount(SubmitBar, {
propsData: {
disabled: true,
buttonText: '提交订单'
@ -81,7 +81,7 @@ describe('PayOrder', () => {
});
it('can not submit when loading', () => {
wrapper = mount(PayOrder, {
wrapper = mount(SubmitBar, {
propsData: {
loading: true,
buttonText: '提交订单'

View File

@ -1,19 +1,19 @@
import DeepSelect from 'packages/deep-select';
import TreeSelect from 'packages/tree-select';
import { mount } from 'avoriaz';
describe('DeepSelect', () => {
describe('TreeSelect', () => {
let wrapper;
afterEach(() => {
wrapper && wrapper.destroy();
});
it('create an empty deep-select', () => {
wrapper = mount(DeepSelect);
it('create an empty tree-select', () => {
wrapper = mount(TreeSelect);
expect(wrapper.hasStyle('height', '0px')).to.be.true;
});
it('create a deep-select correctly', () => {
wrapper = mount(DeepSelect, {
it('create a tree-select correctly', () => {
wrapper = mount(TreeSelect, {
propsData: {
items: [{
text: 'A',
@ -25,13 +25,13 @@ describe('DeepSelect', () => {
maxHeight: 200
}
});
expect(wrapper.hasClass('van-deep-select')).to.be.true;
expect(wrapper.hasClass('van-tree-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', () => {
wrapper = mount(DeepSelect, {
wrapper = mount(TreeSelect, {
propsData: {
items: [{
text: 'A',
@ -58,10 +58,10 @@ describe('DeepSelect', () => {
wrapper.vm.$on('itemclick', item => {
wrapper.vm.activeId = item.id;
});
const secondNav = wrapper.find('.van-deep-select__nitem')[1];
const secondNav = wrapper.find('.van-tree-select__nitem')[1];
secondNav.trigger('click');
expect(wrapper.vm.mainActiveIndex).to.equal(1);
const target = wrapper.find('.van-deep-select__item')[0];
const target = wrapper.find('.van-tree-select__item')[0];
target.trigger('click');
expect(wrapper.vm.activeId).to.equal(345);
});