diff --git a/docs/examples-docs/invalid-goods.md b/docs/examples-docs/invalid-goods.md new file mode 100644 index 000000000..241ab5161 --- /dev/null +++ b/docs/examples-docs/invalid-goods.md @@ -0,0 +1,83 @@ +## InvalidGoods 不可用商品列表 + + + +### 使用指南 +``` javascript +import { InvalidGoods } from 'vant'; + +Vue.component(InvalidGoods.name, InvalidGoods); +``` + +### 代码演示 + +#### 基础用法 + +:::demo 基础用法 +```html + + + + + +``` +::: + +### 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` | diff --git a/docs/src/doc.config.js b/docs/src/doc.config.js index 792b893ce..53912fd7d 100644 --- a/docs/src/doc.config.js +++ b/docs/src/doc.config.js @@ -189,6 +189,10 @@ module.exports = { "path": "/express-way", "title": "ExpressWay 配送方式" }, + { + "path": "/invalid-goods", + "title": "InvalidGoods 不可用商品列表" + }, { "path": "/order-goods", "title": "OrderGoods 下单页商品列表" diff --git a/packages/index.js b/packages/index.js index 86ed944e2..bd8f2a69a 100644 --- a/packages/index.js +++ b/packages/index.js @@ -15,6 +15,7 @@ import ExpressWay from './express-way'; import Field from './field'; import Icon from './icon'; import ImagePreview from './image-preview'; +import InvalidGoods from './invalid-goods'; import Lazyload from './lazyload'; import Loading from './loading'; import NoticeBar from './notice-bar'; @@ -59,6 +60,7 @@ const components = [ ExpressWay, Field, Icon, + InvalidGoods, Loading, NoticeBar, OrderGoods, @@ -117,6 +119,7 @@ export { Field, Icon, ImagePreview, + InvalidGoods, Lazyload, Loading, NoticeBar, diff --git a/packages/invalid-goods/Card.vue b/packages/invalid-goods/Card.vue new file mode 100644 index 000000000..dff9c0e40 --- /dev/null +++ b/packages/invalid-goods/Card.vue @@ -0,0 +1,30 @@ + + + + + 失效 + + + + {{ item.title }} + ¥{{ item.price }} + + + {{ item.sku }} + x{{ item.num }} + + {{ item.unavailable_desc }} + + + + + + diff --git a/packages/invalid-goods/index.vue b/packages/invalid-goods/index.vue new file mode 100644 index 000000000..d0e1079c7 --- /dev/null +++ b/packages/invalid-goods/index.vue @@ -0,0 +1,78 @@ + + + + {{ title }} + + + + + + + + 共{{ formattedGoods.length }}件 + + + + + + + + + + + + + diff --git a/packages/vant-css/src/index.css b/packages/vant-css/src/index.css index 29e48a8cb..8731cbdb4 100644 --- a/packages/vant-css/src/index.css +++ b/packages/vant-css/src/index.css @@ -35,3 +35,4 @@ @import './express-way.css'; @import './pay-order.css'; @import './order-goods.css'; +@import './invalid-goods.css'; diff --git a/packages/vant-css/src/invalid-goods.css b/packages/vant-css/src/invalid-goods.css new file mode 100644 index 000000000..43c0480ce --- /dev/null +++ b/packages/vant-css/src/invalid-goods.css @@ -0,0 +1,121 @@ +@import "./mixins/ellipsis"; + +$van-invalid-goods-photo-size: 90px; + +.van { + &-invalid-goods { + margin: 10px 0; + + &__title { + color: #999; + 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: #666; + font-size: 14px; + padding-right: 8px; + line-height: calc($van-invalid-goods-photo-size + 10px); + background-color: #fff; + text-align: right; + + span { + margin-right: 6px; + vertical-align: middle; + } + } + + &__list { + max-height: 400px; + overflow-y: scroll; + } + } + + &-invalid-goods-card { + color: #999; + 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: #fff; + 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: #f60; + font-size: 12px; + margin-top: 5px; + } + } + + .van-icon-arrow { + color: #666; + font-size: 10px; + } +} \ No newline at end of file diff --git a/test/unit/specs/invalid-goods.spec.js b/test/unit/specs/invalid-goods.spec.js new file mode 100644 index 000000000..308713ce6 --- /dev/null +++ b/test/unit/specs/invalid-goods.spec.js @@ -0,0 +1,81 @@ +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标题' + } + }); + }); +});