add AddressList component

This commit is contained in:
陈嘉涵 2017-09-21 16:26:40 +08:00
parent 309744286e
commit 522655fdd8
14 changed files with 341 additions and 6 deletions

View File

@ -0,0 +1,122 @@
<script>
import { Toast } from 'packages';
export default {
data() {
return {
chosenAddressId: '1',
list: [
{
id: '1',
name: '张三',
tel: '13000000000',
address: '浙江省杭州市西湖区文三路 138 号东方通信大厦 7 楼 501 室'
},
{
id: '2',
name: '李四',
tel: '1310000000',
address: '浙江省杭州市拱墅区莫干山路 50 号'
},
{
id: '3',
name: '王五',
tel: '1320000000',
address: '浙江省杭州市滨江区江南大道 15 号'
}
]
}
},
methods: {
onAdd() {
Toast('新增收货地址');
},
onEdit(item, index) {
Toast('编辑收货地址:' + index);
}
}
}
</script>
## AddressList 地址列表
### 使用指南
``` javascript
import { AddressList } from 'vant';
Vue.component(AddressList.name, AddressList);
```
### 代码演示
#### 基础用法
:::demo 基础用法
```html
<van-address-list
v-model="chosenAddressId"
:list="list"
@add="onAdd"
@edit="onEdit"
/>
```
```javascript
export default {
data() {
return {
chosenAddressId: '1',
list: [
{
id: '1',
name: '张三',
tel: '13000000000',
address: '浙江省杭州市西湖区文三路 138 号东方通信大厦 7 楼 501 室'
},
{
id: '2',
name: '李四',
tel: '1310000000',
address: '浙江省杭州市拱墅区莫干山路 50 号'
}
]
}
},
methods: {
onAdd() {
Toast('新增收货地址');
},
onEdit(item, index) {
Toast('编辑收货地址:' + index);
}
}
}
```
:::
### API
| 参数 | 说明 | 类型 | 默认值 | 可选值 |
|-----------|-----------|-----------|-------------|-------------|
| v-model | 当前选中地址的 id | String | - | - |
| list | 地址列表 | Array | `[]` | - |
| addButtonText | 底部按钮文字 | String | `新增收货地址` | - |
### Event
| 事件名 | 说明 | 参数 |
|-----------|-----------|-----------|
| add | 点击新增按钮时触发 | - |
| edit | 点击编辑按钮时触发 | item: 当前地址对象index: 索引 |
| change | 切换选中的地址时触发 | item: 当前地址对象index: 索引 |
### 数据格式
#### 地址列表字段说明
| key | 说明 | 类型 |
|-----------|-----------|-----------|
| id | 每条地址的唯一标识 | `String | Number` |
| name | 收货人姓名 | `String` |
| tel | 收货人手机号 | `String` |
| address | 收货地址 | `String` |

View File

@ -21,7 +21,7 @@ Vue.component(NoticeBar.name, NoticeBar);
:::demo 基础用法 :::demo 基础用法
```html ```html
<van-notice-bar text="足协杯战线连续第2年上演广州德比战上赛季半决赛上恒大以两回合5-3的总比分淘汰富力。"> <van-notice-bar text="足协杯战线连续第2年上演广州德比战上赛季半决赛上恒大以两回合5-3的总比分淘汰富力。" />
``` ```
::: :::

View File

@ -214,6 +214,10 @@ module.exports = {
{ {
"groupName": "业务组件", "groupName": "业务组件",
"list": [ "list": [
{
"path": "/address-list",
"title": "AddressList 地址列表"
},
{ {
"path": "/area", "path": "/area",
"title": "Area 省市区选择" "title": "Area 省市区选择"

View File

@ -36,6 +36,10 @@ router.afterEach(() => {
window.vueRouter = router; window.vueRouter = router;
if (process.env.NODE_ENV !== 'production') {
Vue.config.productionTip = false;
}
new Vue({ // eslint-disable-line new Vue({ // eslint-disable-line
render: h => h(App), render: h => h(App),
router router

View File

@ -35,6 +35,10 @@ router.afterEach(() => {
window.vueRouter = router; window.vueRouter = router;
if (process.env.NODE_ENV !== 'production') {
Vue.config.productionTip = false;
}
new Vue({ // eslint-disable-line new Vue({ // eslint-disable-line
render: h => h(App), render: h => h(App),
router router

View File

@ -0,0 +1,48 @@
<template>
<div class="van-address-list">
<van-radio-group :value="value" @input="$emit('input', $event)" class="van-address-list__group">
<van-cell-group>
<van-cell v-for="(item, index) in list" :key="item.id">
<van-radio :name="item.id" @click="$emit('change', item, index)">
<div class="van-address-list__name">{{ item.name }}{{ item.tel }}</div>
<div class="van-address-list__address">收货地址{{ item.address }}</div>
</van-radio>
<van-icon name="edit" class="van-address-list__edit" @click="$emit('edit', item, index)" />
</van-cell>
</van-cell-group>
</van-radio-group>
<van-cell icon="add" class="van-address-list__add van-hairline--top" @click="$emit('add')" :title="addButtonText" isLink />
</div>
</template>
<script>
import Icon from '../icon';
import Cell from '../cell';
import CellGroup from '../cell-group';
import Radio from '../radio';
import RadioGroup from '../radio-group';
export default {
name: 'van-address-list',
components: {
[Icon.name]: Icon,
[Cell.name]: Cell,
[Radio.name]: Radio,
[CellGroup.name]: CellGroup,
[RadioGroup.name]: RadioGroup
},
props: {
value: [String, Number],
list: {
type: Array,
default: () => []
},
addButtonText: {
type: String,
default: '新增收货地址'
}
}
};
</script>

View File

@ -1,4 +1,5 @@
import Actionsheet from './actionsheet'; import Actionsheet from './actionsheet';
import AddressList from './address-list';
import Area from './area'; import Area from './area';
import Badge from './badge'; import Badge from './badge';
import BadgeGroup from './badge-group'; import BadgeGroup from './badge-group';
@ -55,6 +56,7 @@ import Waterfall from './waterfall';
const version = '0.9.6'; const version = '0.9.6';
const components = [ const components = [
Actionsheet, Actionsheet,
AddressList,
Area, Area,
Badge, Badge,
BadgeGroup, BadgeGroup,
@ -121,6 +123,7 @@ export {
install, install,
version, version,
Actionsheet, Actionsheet,
AddressList,
Area, Area,
Badge, Badge,
BadgeGroup, BadgeGroup,

View File

@ -57,10 +57,10 @@ export default {
}, },
contentStyle() { contentStyle() {
return { return {
left: -this.offsetWidth + 'px', transform: `translate3d(${-this.offsetWidth}px, 0, 0)`,
transitionDelay: this.delay + 's', transitionDelay: this.delay + 's',
transitionDuration: this.duration + 's', transitionDuration: this.duration + 's',
transitionProperty: this.diableTransition ? 'none' : 'left' transitionProperty: this.diableTransition ? 'none' : 'all'
}; };
} }
}, },

View File

@ -0,0 +1,69 @@
@import './common/var.css';
.van-address-list {
height: 100%;
.van-cell__value {
color: $text-color;
padding-right: 34px;
position: relative;
}
.van-radio__label {
margin-left: 32px;
}
.van-radio__input {
top: 50%;
left: 0;
position: absolute;
transform: translate(0, -50%);
}
.van-icon-checked {
color: $blue;
}
&__group {
height: 100%;
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
}
&__name {
font-size: 14px;
line-height: 1.5;
}
&__address {
font-size: 12px;
line-height: 1.5;
color: $gray-darker;
}
&__edit {
position: absolute;
top: 50%;
right: 4px;
font-size: 24px;
color: $gray-dark;
transform: translate(0, -50%);
}
&__add {
position: fixed;
left: 0;
bottom: 0;
z-index: 9999;
padding-left: 15px;
.van-cell__text {
font-size: 16px;
}
.van-icon-add {
color: $blue;
font-size: 20px;
}
}
}

View File

@ -1,5 +1,5 @@
/** /**
* 基本样式入口 * Entry of basic styles
*/ */
@import "./common/var.css"; @import "./common/var.css";

View File

@ -8,6 +8,7 @@ $van-checkbox-size: 18px;
.van-icon-success { .van-icon-success {
color: #fff; color: #fff;
display: block; display: block;
line-height: 1;
font-size: 14px; font-size: 14px;
text-align: center; text-align: center;
pointer-events: none; pointer-events: none;

View File

@ -1,5 +1,5 @@
/** /**
* style entry * Entry of all component's style
*/ */
/* base */ /* base */
@ -50,6 +50,7 @@
@import './tree-select.css'; @import './tree-select.css';
/* business components */ /* business components */
@import './address-list.css';
@import './coupon-list.css'; @import './coupon-list.css';
@import './goods-action.css'; @import './goods-action.css';
@import './submit-bar.css'; @import './submit-bar.css';

View File

@ -30,7 +30,6 @@
&__content { &__content {
position: absolute; position: absolute;
white-space: nowrap; white-space: nowrap;
transition-property: left;
transition-timing-function: linear; transition-timing-function: linear;
} }
} }

View File

@ -0,0 +1,80 @@
import { mount } from 'avoriaz';
import AddressList from 'packages/address-list';
const list = [
{
id: '1',
name: '张三',
tel: '13000000000',
address: '浙江省杭州市西湖区文三路 138 号东方通信大厦 7 楼 501 室'
},
{
id: '2',
name: '李四',
tel: '1310000000',
address: '浙江省杭州市拱墅区莫干山路 50 号'
},
{
id: '3',
name: '王五',
tel: '1320000000',
address: '浙江省杭州市滨江区江南大道 15 号'
}
];
describe('AddressList', () => {
let wrapper;
afterEach(() => {
wrapper && wrapper.destroy();
});
it('create a AddressList', () => {
wrapper = mount(AddressList);
expect(wrapper.hasClass('van-address-list')).to.be.true;
});
it('create a AddressList with three items', () => {
wrapper = mount(AddressList, {
propsData: {
value: '1',
list
}
});
expect(wrapper.find('.van-address-list__group .van-cell').length).to.equal(3);
expect(wrapper.find('.van-icon-checked').length).to.equal(1);
});
it('listen to add & edit event', (done) => {
wrapper = mount(AddressList, {
propsData: {
list
}
});
const add = sinon.spy();
wrapper.vm.$on('add', add);
wrapper.find('.van-address-list__add')[0].trigger('click');
expect(add.calledOnce).to.be.true;
wrapper.vm.$on('edit', (item, index) => {
expect(index).to.equal(0);
done();
});
wrapper.find('.van-address-list__edit')[0].trigger('click');
});
it('listen to change event', (done) => {
wrapper = mount(AddressList, {
propsData: {
value: '1',
list
}
});
wrapper.vm.$on('change', (item, index) => {
expect(item.id).to.equal('3');
done();
});
wrapper.find('.van-radio')[2].trigger('click');
});
});