mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
commit
bfa224f005
@ -7,6 +7,11 @@
|
||||
&--bottom-action {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
&--small,
|
||||
&--normal {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.zan-doc-demo-block {
|
||||
|
@ -67,19 +67,13 @@ export default {
|
||||
'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);
|
||||
onChange(item) {
|
||||
Toast(`配送方式更换为:${item.postage_title}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -93,7 +87,7 @@ export default {
|
||||
```html
|
||||
<van-cell-group>
|
||||
<van-express-way
|
||||
:value="-1"
|
||||
:value="1"
|
||||
:express-list="expressList"
|
||||
:editable="false"
|
||||
@change="onChange"
|
||||
|
229
docs/examples-docs/order-goods.md
Normal file
229
docs/examples-docs/order-goods.md
Normal file
@ -0,0 +1,229 @@
|
||||
## 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
|
||||
<template>
|
||||
<van-order-goods
|
||||
v-model="message1"
|
||||
shop-name="起码运动馆"
|
||||
:price="1050"
|
||||
:item-list="itemList1"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
message1: '',
|
||||
itemList1: [{
|
||||
img_url: '//img.yzcdn.cn/...',
|
||||
pay_price: 1050,
|
||||
title: '商品 A',
|
||||
num: '1'
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
:::
|
||||
|
||||
#### 积分商品
|
||||
|
||||
:::demo 积分商品
|
||||
```html
|
||||
<template>
|
||||
<van-order-goods
|
||||
v-model="message2"
|
||||
shop-name="起码运动馆"
|
||||
:item-list="itemList2"
|
||||
:price="50"
|
||||
:points="200"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
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' }
|
||||
]
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
:::
|
||||
|
||||
#### 预售商品
|
||||
|
||||
:::demo 预售商品
|
||||
```html
|
||||
<template>
|
||||
<van-order-goods
|
||||
v-model="message3"
|
||||
shop-name="起码运动馆"
|
||||
:price="1050"
|
||||
:item-list="itemList3"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
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
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
:::
|
||||
|
||||
#### 商品为空
|
||||
|
||||
:::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` |
|
||||
|
||||
### Slot
|
||||
| name | 描述 |
|
||||
|-----------|-----------|
|
||||
| 默认 | 在商品列表和留言之间插入内容 |
|
||||
| top | 在标题和商品列表之间插入内容 |
|
||||
| bottom | 在合计价格下方插入内容 |
|
@ -189,6 +189,10 @@ module.exports = {
|
||||
"path": "/express-way",
|
||||
"title": "ExpressWay 配送方式"
|
||||
},
|
||||
{
|
||||
"path": "/order-goods",
|
||||
"title": "OrderGoods 下单页商品列表"
|
||||
},
|
||||
{
|
||||
"path": "/pay-order",
|
||||
"title": "PayOrder 提交订单栏"
|
||||
|
@ -117,6 +117,6 @@
|
||||
"webpack": "^3.5.5",
|
||||
"webpack-dev-server": "^2.7.1",
|
||||
"webpack-merge": "^4.1.0",
|
||||
"zan-doc": "^0.2.6"
|
||||
"zan-doc": "^0.2.9"
|
||||
}
|
||||
}
|
||||
|
@ -19,10 +19,10 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Option from './Option.vue';
|
||||
import Actionsheet from '../actionsheet';
|
||||
import Option from './Option';
|
||||
import Cell from '../cell';
|
||||
import CellGroup from '../cell-group';
|
||||
import Actionsheet from '../actionsheet';
|
||||
|
||||
export default {
|
||||
name: 'van-express-way',
|
||||
|
@ -18,6 +18,7 @@ import ImagePreview from './image-preview';
|
||||
import Lazyload from './lazyload';
|
||||
import Loading from './loading';
|
||||
import NoticeBar from './notice-bar';
|
||||
import OrderGoods from './order-goods';
|
||||
import Panel from './panel';
|
||||
import PayOrder from './pay-order';
|
||||
import Picker from './picker';
|
||||
@ -60,6 +61,7 @@ const components = [
|
||||
Icon,
|
||||
Loading,
|
||||
NoticeBar,
|
||||
OrderGoods,
|
||||
Panel,
|
||||
PayOrder,
|
||||
Picker,
|
||||
@ -118,6 +120,7 @@ export {
|
||||
Lazyload,
|
||||
Loading,
|
||||
NoticeBar,
|
||||
OrderGoods,
|
||||
Panel,
|
||||
PayOrder,
|
||||
Picker,
|
||||
|
102
packages/order-goods/Card.vue
Normal file
102
packages/order-goods/Card.vue
Normal file
@ -0,0 +1,102 @@
|
||||
<template>
|
||||
<div class="van-order-goods-card">
|
||||
<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" 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">
|
||||
<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>
|
31
packages/order-goods/Empty.vue
Normal file
31
packages/order-goods/Empty.vue
Normal file
@ -0,0 +1,31 @@
|
||||
<template>
|
||||
<div class="van-order-goods-empty">
|
||||
<img :src="icon" />
|
||||
<p>{{ message }}</p>
|
||||
<van-button @click="onClickButton">{{ 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
|
||||
},
|
||||
|
||||
methods: {
|
||||
onClickButton() {
|
||||
history.back();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
26
packages/order-goods/Header.vue
Normal file
26
packages/order-goods/Header.vue
Normal file
@ -0,0 +1,26 @@
|
||||
<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>
|
50
packages/order-goods/Message.vue
Normal file
50
packages/order-goods/Message.vue
Normal file
@ -0,0 +1,50 @@
|
||||
<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>
|
32
packages/order-goods/Price.vue
Normal file
32
packages/order-goods/Price.vue
Normal file
@ -0,0 +1,32 @@
|
||||
<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>
|
113
packages/order-goods/index.vue
Normal file
113
packages/order-goods/index.vue
Normal file
@ -0,0 +1,113 @@
|
||||
<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"
|
||||
/>
|
||||
<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>
|
13
packages/order-goods/utils.js
Normal file
13
packages/order-goods/utils.js
Normal file
@ -0,0 +1,13 @@
|
||||
/**
|
||||
* 拼接商品价格(金额和积分)
|
||||
*/
|
||||
export function getTotalPrice(price, points) {
|
||||
const arr = [];
|
||||
if (points) {
|
||||
arr.push(points + '积分');
|
||||
}
|
||||
if (price) {
|
||||
arr.push('¥' + (price / 100).toFixed(2));
|
||||
}
|
||||
return arr.join(' + ');
|
||||
}
|
@ -34,3 +34,4 @@
|
||||
@import './switch-cell.css';
|
||||
@import './express-way.css';
|
||||
@import './pay-order.css';
|
||||
@import './order-goods.css';
|
||||
|
214
packages/vant-css/src/order-goods.css
Normal file
214
packages/vant-css/src/order-goods.css
Normal file
@ -0,0 +1,214 @@
|
||||
@import "./mixins/border_retina";
|
||||
|
||||
.van-order-goods {
|
||||
background-color: #fff;
|
||||
|
||||
&-card {
|
||||
margin-left: -15px;
|
||||
position: relative;
|
||||
background-color: #fafafa;
|
||||
|
||||
&:not(:first-child),
|
||||
&__delivery {
|
||||
&::after {
|
||||
@mixin border-retina (top);
|
||||
}
|
||||
}
|
||||
|
||||
&__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: #fff;
|
||||
background-color: #4b0;
|
||||
}
|
||||
|
||||
&__tag-red {
|
||||
color: #ed5050;
|
||||
padding: 5px 8px;
|
||||
border: 1px solid #ed5050;
|
||||
}
|
||||
|
||||
&__delivery {
|
||||
padding-left: 15px;
|
||||
background-color: transparent;
|
||||
|
||||
.van-cell__value {
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
|
||||
&__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: #f8f8f8;
|
||||
|
||||
h2 {
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
padding: 5px 0 5px 10px;
|
||||
}
|
||||
|
||||
ul {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
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;
|
||||
position: relative;
|
||||
|
||||
&:not(:last-child)::after {
|
||||
@mixin border-retina (bottom);
|
||||
}
|
||||
|
||||
img {
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-empty {
|
||||
margin-left: -15px;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
@mixin border-retina (top);
|
||||
}
|
||||
|
||||
p {
|
||||
color: #999;
|
||||
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: #e5e5e5;
|
||||
}
|
||||
}
|
||||
|
||||
&-header {
|
||||
line-height: 50px;
|
||||
|
||||
a,
|
||||
img,
|
||||
.van-icon {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.van-icon {
|
||||
font-size: 18px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #333;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
img {
|
||||
height: 14px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
&-message {
|
||||
textarea {
|
||||
color: #666;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
height: 22px;
|
||||
border: none;
|
||||
resize: none;
|
||||
outline: none;
|
||||
display: block;
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
transition: height .3s ease-in-out;
|
||||
}
|
||||
|
||||
textarea&-focused {
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
p {
|
||||
color: #666;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.van-cell__title {
|
||||
width: 75px;
|
||||
}
|
||||
}
|
||||
|
||||
&-price {
|
||||
.van-cell__value {
|
||||
color: #f44;
|
||||
}
|
||||
}
|
||||
}
|
313
test/unit/specs/order-goods.spec.js
Normal file
313
test/unit/specs/order-goods.spec.js
Normal file
@ -0,0 +1,313 @@
|
||||
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: []
|
||||
}
|
||||
});
|
||||
|
||||
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'
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
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', () => {
|
||||
wrapper = mount(OrderGoods, {
|
||||
attachToDocument: true,
|
||||
propsData: {
|
||||
itemList: [item1],
|
||||
message: ''
|
||||
}
|
||||
});
|
||||
|
||||
wrapper.vm.$on('input', val => {
|
||||
wrapper.value = val;
|
||||
});
|
||||
|
||||
const textarea = wrapper.find('textarea')[0];
|
||||
textarea.value = '测试留言';
|
||||
textarea.trigger('input');
|
||||
|
||||
wrapper.vm.$nextTick(() => {
|
||||
expect(wrapper.value).to.equal('测试留言');
|
||||
});
|
||||
});
|
||||
|
||||
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
|
||||
}
|
||||
});
|
||||
|
||||
wrapper.vm.$on('input', val => {
|
||||
wrapper.value = val;
|
||||
});
|
||||
|
||||
wrapper.vm.$nextTick(() => {
|
||||
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', () => {
|
||||
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'
|
||||
}
|
||||
}
|
||||
});
|
||||
}, 300);
|
||||
});
|
||||
|
||||
it('multi items', () => {
|
||||
wrapper = mount(OrderGoods, {
|
||||
attachToDocument: true,
|
||||
propsData: {
|
||||
itemList: [item1, item2, item3]
|
||||
}
|
||||
});
|
||||
|
||||
DOMChecker(wrapper, {
|
||||
count: {
|
||||
'.van-order-goods-card': 3
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
@ -1,7 +1,6 @@
|
||||
import Picker from 'packages/picker';
|
||||
import PickerColumn from 'packages/picker/picker-column';
|
||||
import { mount } from 'avoriaz';
|
||||
import Wrapper from 'avoriaz/dist/Wrapper';
|
||||
|
||||
const itemHeight = 44;
|
||||
|
||||
|
@ -7970,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.6:
|
||||
version "0.2.6"
|
||||
resolved "https://registry.npmjs.org/zan-doc/-/zan-doc-0.2.6.tgz#27cc789460c32f6bed7687e050e2d9063b2725d5"
|
||||
zan-doc@^0.2.9:
|
||||
version "0.2.9"
|
||||
resolved "https://registry.npmjs.org/zan-doc/-/zan-doc-0.2.9.tgz#9d8787f2a6502686f3c44dc4ced9d8ca0fbe3d4e"
|
||||
dependencies:
|
||||
cheerio "0.22.0"
|
||||
decamelize "^1.2.0"
|
||||
|
Loading…
x
Reference in New Issue
Block a user