[improvement] rename packages dir to src (#3659)

This commit is contained in:
neverland
2019-06-27 11:25:57 +08:00
committed by GitHub
parent 8489918dca
commit 75c79b7044
619 changed files with 21 additions and 21 deletions
+92
View File
@@ -0,0 +1,92 @@
<template>
<demo-section background="white">
<demo-block :title="$t('basicUsage')">
<van-card
num="2"
price="2.00"
:desc="$t('desc')"
:title="$t('title')"
:thumb="imageURL"
/>
</demo-block>
<demo-block :title="$t('discountInfo')">
<van-card
num="2"
price="2.00"
origin-price="10.00"
:tag="$t('tag')"
:desc="$t('desc')"
:title="$t('title')"
:thumb="imageURL"
/>
</demo-block>
<demo-block :title="$t('customContent')">
<van-card
num="2"
price="2.00"
:desc="$t('desc')"
:title="$t('title')"
:thumb="imageURL"
>
<template #tags>
<div>
<van-tag
plain
type="danger"
style="margin-right: 5px;"
>
标签
</van-tag>
<van-tag
plain
type="danger"
>
标签
</van-tag>
</div>
</template>
<template #footer>
<div>
<van-button
round
size="mini"
>
{{ $t('button') }}
</van-button>
<van-button
round
size="mini"
>
{{ $t('button') }}
</van-button>
</div>
</template>
</van-card>
</demo-block>
</demo-section>
</template>
<script>
export default {
i18n: {
'zh-CN': {
title: '商品名称',
discountInfo: '营销信息',
customContent: '自定义内容'
},
'en-US': {
discountInfo: 'Discount Info',
customContent: 'Custom Content'
}
},
data() {
return {
imageURL: 'https://img.yzcdn.cn/vant/t-thirt.jpg'
};
}
};
</script>
+99
View File
@@ -0,0 +1,99 @@
# Card
### Install
``` javascript
import { Card } from 'vant';
Vue.use(Card);
```
## Usage
### Basic Usage
```html
<van-card
num="2"
price="2.00"
title="Title"
desc="Description"
thumb="https://img.yzcdn.cn/vant/t-thirt.jpg"
/>
```
### Discount Info
```html
<van-card
num="2"
tag="Tag"
price="2.00"
title="Title"
desc="Description"
origin-price="10.00"
thumb="https://img.yzcdn.cn/vant/t-thirt.jpg"
/>
```
### Custom Content
Use slot to custom content.
```html
<van-card
num="2"
title="Title"
desc="Description"
price="2.00"
thumb="https://img.yzcdn.cn/vant/t-thirt.jpg"
>
<div slot="tags">
<van-tag plain type="danger">Tag</van-tag>
<van-tag plain type="danger">Tag</van-tag>
</div>
<div slot="footer">
<van-button size="mini">Button</van-button>
<van-button size="mini">Button</van-button>
</div>
</van-card>
```
## API
### Props
| Attribute | Description | Type | Default |
|------|------|------|------|
| thumb | Left thumb image URL | `String` | - |
| title | Title | `String` | - |
| desc | Description | `String` | - |
| tag | Tag | `String` | - |
| num | Number | `String | Number` | - |
| price | Price | `String | Number` | - |
| origin-price | Origin price | `String | Number` | - |
| centered | Whether content vertical centered | `Boolean` | `false` |
| currency | Currency symbol | `String` | `¥` |
| thumb-link | Thumb link URL | `String` | - |
| lazy-load | Whether to enable thumb lazy loadshould register [Lazyload](#/en-US/lazyload) component | `Boolean` | `false` |
### Events
| Event | Description | Arguments |
|------|------|------|
| click | Triggered when clicked | - |
| click-thumb | Triggered when thumb clicked | - |
### Slots
| Name | Description |
|------|------|
| title | Custom title |
| desc | Custom description |
| num | Custom num |
| price | Custom price |
| origin-price | Custom origin price |
| bottom | Custom price bottom |
| thumb | Custom thumb |
| tag | Custom thumb tag |
| tags | Custom tags |
| footer | Custom footer |
+96
View File
@@ -0,0 +1,96 @@
@import '../style/var';
@import '../style/mixins/ellipsis';
.van-card {
position: relative;
box-sizing: border-box;
padding: @card-padding;
color: @card-text-color;
font-size: @card-font-size;
background-color: @card-background-color;
&:not(:first-child) {
margin-top: 10px;
}
&__header {
display: flex;
}
&__thumb {
position: relative;
flex: none;
width: @card-thumb-size;
height: @card-thumb-size;
margin-right: 10px;
}
&__content {
position: relative;
display: flex;
flex: 1;
flex-direction: column;
min-width: 0; /* hack for flex box ellipsis */
min-height: @card-thumb-size;
&--centered {
justify-content: center;
}
}
&__title,
&__desc {
word-break: break-all;
}
&__title {
max-height: 32px;
font-weight: 500;
line-height: @card-title-line-height;
.multi-ellipsis(2);
}
&__desc {
max-height: @card-desc-line-height;
color: @card-desc-color;
line-height: @card-desc-line-height;
}
&__bottom {
line-height: 20px;
}
&__price {
display: inline-block;
color: @card-price-color;
font-weight: 500;
}
&__origin-price {
display: inline-block;
margin-left: 5px;
color: @card-origin-price-color;
font-size: @card-origin-price-font-size;
text-decoration: line-through;
}
&__num {
float: right;
}
&__tag {
position: absolute;
top: 2px;
left: 0;
}
&__footer {
flex: none;
text-align: right;
.van-button {
margin-left: 5px;
}
}
}
+190
View File
@@ -0,0 +1,190 @@
import { createNamespace, isDef } from '../utils';
import { emit, inherit } from '../utils/functional';
import Tag from '../tag';
import Image from '../image';
// Types
import { CreateElement, RenderContext } from 'vue/types';
import { DefaultSlots, ScopedSlot } from '../utils/types';
export type CardProps = {
tag?: string;
num?: number | string;
desc?: string;
thumb?: string;
title?: string;
price?: number | string;
currency: string;
centered?: boolean;
lazyLoad?: boolean;
thumbLink?: string;
originPrice?: number | string;
};
export type CardSlots = DefaultSlots & {
num?: ScopedSlot;
tag?: ScopedSlot;
tags?: ScopedSlot;
desc?: ScopedSlot;
title?: ScopedSlot;
thumb?: ScopedSlot;
price?: ScopedSlot;
bottom?: ScopedSlot;
footer?: ScopedSlot;
'origin-price'?: ScopedSlot;
};
export type CardEvents = {
onClick?(event: Event): void;
};
const [createComponent, bem] = createNamespace('card');
function Card(
h: CreateElement,
props: CardProps,
slots: CardSlots,
ctx: RenderContext<CardProps>
) {
const { thumb } = props;
const showNum = slots.num || isDef(props.num);
const showPrice = slots.price || isDef(props.price);
const showOriginPrice = slots['origin-price'] || isDef(props.originPrice);
const showBottom = showNum || showPrice || showOriginPrice;
const onThumbClick = () => {
emit(ctx, 'click-thumb');
};
function ThumbTag() {
if (slots.tag || props.tag) {
return (
<div class={bem('tag')}>
{slots.tag ? (
slots.tag()
) : (
<Tag mark type="danger">
{props.tag}
</Tag>
)}
</div>
);
}
}
function Thumb() {
if (slots.thumb || thumb) {
return (
<a href={props.thumbLink} class={bem('thumb')} onClick={onThumbClick}>
{slots.thumb ? (
slots.thumb()
) : (
<Image
src={thumb}
width="100%"
height="100%"
fit="contain"
lazy-load={props.lazyLoad}
/>
)}
{ThumbTag()}
</a>
);
}
}
function Title() {
if (slots.title) {
return slots.title();
}
if (props.title) {
return <div class={bem('title')}>{props.title}</div>;
}
}
function Desc() {
if (slots.desc) {
return slots.desc();
}
if (props.desc) {
return <div class={[bem('desc'), 'van-ellipsis']}>{props.desc}</div>;
}
}
function Price() {
if (showPrice) {
return (
<div class={bem('price')}>
{slots.price ? slots.price() : `${props.currency} ${props.price}`}
</div>
);
}
}
function OriginPrice() {
if (showOriginPrice) {
const slot = slots['origin-price'];
return (
<div class={bem('origin-price')}>
{slot ? slot() : `${props.currency} ${props.originPrice}`}
</div>
);
}
}
function Num() {
if (showNum) {
return <div class={bem('num')}>{slots.num ? slots.num() : `x ${props.num}`}</div>;
}
}
function Footer() {
if (slots.footer) {
return <div class={bem('footer')}>{slots.footer()}</div>;
}
}
return (
<div class={bem()} {...inherit(ctx, true)}>
<div class={bem('header')}>
{Thumb()}
<div class={bem('content', { centered: props.centered })}>
{Title()}
{Desc()}
{slots.tags && slots.tags()}
{showBottom && (
<div class="van-card__bottom">
{Price()}
{OriginPrice()}
{Num()}
{slots.bottom && slots.bottom()}
</div>
)}
</div>
</div>
{Footer()}
</div>
);
}
Card.props = {
tag: String,
desc: String,
thumb: String,
title: String,
centered: Boolean,
lazyLoad: Boolean,
thumbLink: String,
num: [Number, String],
price: [Number, String],
originPrice: [Number, String],
currency: {
type: String,
default: '¥'
}
};
export default createComponent<CardProps, CardEvents>(Card);
@@ -0,0 +1,77 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`renders demo correctly 1`] = `
<div>
<div>
<div class="van-card">
<div class="van-card__header"><a class="van-card__thumb">
<div class="van-image" style="width: 100%; height: 100%;"><img src="https://img.yzcdn.cn/vant/t-thirt.jpg" class="van-image__img" style="object-fit: contain;">
<div class="van-image__loading"><i class="van-icon van-icon-photo-o" style="font-size: 22px;">
<!----></i></div>
</div>
</a>
<div class="van-card__content">
<div class="van-card__title">商品名称</div>
<div class="van-card__desc van-ellipsis">描述信息</div>
<div class="van-card__bottom">
<div class="van-card__price">¥ 2.00</div>
<div class="van-card__num">x 2</div>
</div>
</div>
</div>
</div>
</div>
<div>
<div class="van-card">
<div class="van-card__header"><a class="van-card__thumb">
<div class="van-image" style="width: 100%; height: 100%;"><img src="https://img.yzcdn.cn/vant/t-thirt.jpg" class="van-image__img" style="object-fit: contain;">
<div class="van-image__loading"><i class="van-icon van-icon-photo-o" style="font-size: 22px;">
<!----></i></div>
</div>
<div class="van-card__tag"><span class="van-tag van-tag--mark" style="background-color: rgb(255, 68, 68);">标签</span></div>
</a>
<div class="van-card__content">
<div class="van-card__title">商品名称</div>
<div class="van-card__desc van-ellipsis">描述信息</div>
<div class="van-card__bottom">
<div class="van-card__price">¥ 2.00</div>
<div class="van-card__origin-price">¥ 10.00</div>
<div class="van-card__num">x 2</div>
</div>
</div>
</div>
</div>
</div>
<div>
<div class="van-card">
<div class="van-card__header"><a class="van-card__thumb">
<div class="van-image" style="width: 100%; height: 100%;"><img src="https://img.yzcdn.cn/vant/t-thirt.jpg" class="van-image__img" style="object-fit: contain;">
<div class="van-image__loading"><i class="van-icon van-icon-photo-o" style="font-size: 22px;">
<!----></i></div>
</div>
</a>
<div class="van-card__content">
<div class="van-card__title">商品名称</div>
<div class="van-card__desc van-ellipsis">描述信息</div>
<div><span class="van-tag van-tag--plain van-hairline--surround" style="margin-right: 5px; color: rgb(255, 68, 68);">
标签
</span> <span class="van-tag van-tag--plain van-hairline--surround" style="color: rgb(255, 68, 68);">
标签
</span></div>
<div class="van-card__bottom">
<div class="van-card__price">¥ 2.00</div>
<div class="van-card__num">x 2</div>
</div>
</div>
</div>
<div class="van-card__footer">
<div><button class="van-button van-button--default van-button--mini van-button--round"><span class="van-button__text">
按钮
</span></button> <button class="van-button van-button--default van-button--mini van-button--round"><span class="van-button__text">
按钮
</span></button></div>
</div>
</div>
</div>
</div>
`;
@@ -0,0 +1,54 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`render bottom slot 1`] = `
<div class="van-card">
<div class="van-card__header">
<div class="van-card__content">
<div class="van-card__bottom">
<div class="van-card__price">¥ 100</div>Custom Bottom
</div>
</div>
</div>
</div>
`;
exports[`render origin-price slot 1`] = `
<div class="van-card">
<div class="van-card__header">
<div class="van-card__content">
<div class="van-card__bottom">
<div class="van-card__origin-price">Custom Origin Price</div>
</div>
</div>
</div>
</div>
`;
exports[`render price & num slot 1`] = `
<div class="van-card">
<div class="van-card__header">
<div class="van-card__content">
<div class="van-card__bottom">
<div class="van-card__price">Custom Price</div>
<div class="van-card__num">Custom Num</div>
</div>
</div>
</div>
</div>
`;
exports[`render thumb & tag slot 1`] = `
<div class="van-card">
<div class="van-card__header"><a class="van-card__thumb">Custom Thumb<div class="van-card__tag">Custom Tag</div></a>
<div class="van-card__content"></div>
</div>
</div>
`;
exports[`render title & desc slot 1`] = `
<div class="van-card">
<div class="van-card__header">
<div class="van-card__content">Custom TitleCustom desc</div>
</div>
</div>
`;
+4
View File
@@ -0,0 +1,4 @@
import Demo from '../demo';
import demoTest from '../../../test/demo-test';
demoTest(Demo);
+58
View File
@@ -0,0 +1,58 @@
import Card from '..';
import { mount } from '../../../test/utils';
test('render price & num slot', () => {
const wrapper = mount(Card, {
scopedSlots: {
num: () => 'Custom Num',
price: () => 'Custom Price'
}
});
expect(wrapper).toMatchSnapshot();
});
test('render origin-price slot', () => {
const wrapper = mount(Card, {
scopedSlots: {
'origin-price': () => 'Custom Origin Price'
}
});
expect(wrapper).toMatchSnapshot();
});
test('render bottom slot', () => {
const wrapper = mount(Card, {
propsData: {
price: 100
},
scopedSlots: {
bottom: () => 'Custom Bottom'
}
});
expect(wrapper).toMatchSnapshot();
});
test('render thumb & tag slot', () => {
const wrapper = mount(Card, {
scopedSlots: {
tag: () => 'Custom Tag',
thumb: () => 'Custom Thumb'
}
});
expect(wrapper).toMatchSnapshot();
});
test('render title & desc slot', () => {
const wrapper = mount(Card, {
scopedSlots: {
title: () => 'Custom Title',
desc: () => 'Custom desc'
}
});
expect(wrapper).toMatchSnapshot();
});
+101
View File
@@ -0,0 +1,101 @@
# Card 卡片
### 引入
``` javascript
import { Card } from 'vant';
Vue.use(Card);
```
## 代码演示
### 基础用法
```html
<van-card
num="2"
price="2.00"
desc="描述信息"
title="商品标题"
thumb="https://img.yzcdn.cn/vant/t-thirt.jpg"
/>
```
### 营销信息
通过`origin-price`设置商品原价,通过`tag`设置商品左上角标签
```html
<van-card
num="2"
tag="标签"
price="2.00"
desc="描述信息"
title="商品标题"
thumb="https://img.yzcdn.cn/vant/t-thirt.jpg"
origin-price="10.00"
/>
```
### 自定义内容
`Card`组件提供了多个插槽,可以灵活地自定义内容
```html
<van-card
num="2"
price="2.00"
desc="描述信息"
title="商品标题"
thumb="https://img.yzcdn.cn/vant/t-thirt.jpg"
>
<div slot="tags">
<van-tag plain type="danger">标签</van-tag>
<van-tag plain type="danger">标签</van-tag>
</div>
<div slot="footer">
<van-button size="mini">按钮</van-button>
<van-button size="mini">按钮</van-button>
</div>
</van-card>
```
## API
### Props
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|------|------|------|------|------|
| thumb | 左侧图片 URL | `String` | - | - |
| title | 标题 | `String` | - | - |
| desc | 描述 | `String` | - | - |
| tag | 图片角标 | `String` | - | 1.3.4 |
| num | 商品数量 | `String | Number` | - | - |
| price | 商品价格 | `String | Number` | - | - |
| origin-price | 商品划线原价 | `String | Number` | - | 1.3.6 |
| centered | 内容是否垂直居中 | `Boolean` | `false` | - |
| currency | 货币符号 | `String` | `¥` | - |
| thumb-link | 点击左侧图片后的跳转链接 | `String` | - | 1.3.4 |
| lazy-load | 是否开启图片懒加载,须配合 [Lazyload](#/zh-CN/lazyload) 组件使用 | `Boolean` | `false` | 1.5.0 |
### Events
| 事件名 | 说明 | 回调参数 |
|------|------|------|
| click | 点击时触发 | - |
| click-thumb | 点击自定义图片时触发 | - |
### Slots
| 名称 | 说明 |
|------|------|
| title | 自定义标题 |
| desc | 自定义描述 |
| num | 自定义数量 |
| price | 自定义价格 |
| origin-price | 自定义商品原价 |
| bottom | 自定义价格下方区域 |
| thumb | 自定义图片 |
| tag | 自定义图片角标 |
| tags | 自定义描述下方标签区域 |
| footer | 自定义右下角内容 |