Merge branch '2.x' into dev

This commit is contained in:
chenjiahan
2020-11-03 20:47:09 +08:00
20 changed files with 838 additions and 583 deletions
+74
View File
@@ -0,0 +1,74 @@
# ContactEdit
### Install
```js
import { createApp } from 'vue';
import { ContactEdit } from 'vant';
const app = createApp();
app.use(ContactEdit);
```
## Usage
### Basic Usage
```html
<van-contact-edit
is-edit
show-set-default
:contact-info="editingContact"
set-default-label="Set as the default contact"
@save="onSave"
@delete="onDelete"
/>
```
```js
import { Toast } from 'vant';
export default {
data() {
return {
editingContact: {},
};
},
methods: {
onSave(contactInfo) {
Toast('Save');
},
onDelete(contactInfo) {
Toast('Delete');
},
},
};
```
## API
### Props
| Attribute | Description | Type | Default |
| --- | --- | --- | --- |
| contact-info | Contact Info | _Contact_ | `[]` |
| is-edit | Whether is editing | _boolean_ | `false` |
| is-saving | Whether to show save button loading status | _boolean_ | `false` |
| is-deleting | Whether to show delete button loading status | _boolean_ | `false` |
| tel-validator | The method to validate tel | _(tel: string) => boolean_ | - |
| show-set-default `v2.3.0` | Whether to show default contact switch | _boolean_ | `false` |
| set-default-label `v2.3.0` | default contact switch label | _string_ | - |
### Events
| Event | Description | Arguments |
| ------ | ---------------------------------- | --------------------- |
| save | Triggered when click save button | contentcontact info |
| delete | Triggered when click delete button | contentcontact info |
### Data Structure of Contact
| key | Description | Type |
| ---- | ----------- | -------- |
| name | Name | _string_ |
| tel | Phone | _string_ |
+78
View File
@@ -0,0 +1,78 @@
# ContactEdit 联系人编辑
### 介绍
编辑并保存联系人信息。
### 引入
```js
import { createApp } from 'vue';
import { ContactEdit } from 'vant';
const app = createApp();
app.use(ContactEdit);
```
## 代码演示
### 基础用法
```html
<van-contact-edit
is-edit
show-set-default
:contact-info="editingContact"
set-default-label="设为默认联系人"
@save="onSave"
@delete="onDelete"
/>
```
```js
import { Toast } from 'vant';
export default {
data() {
return {
editingContact: {},
};
},
methods: {
onSave(contactInfo) {
Toast('保存');
},
onDelete(contactInfo) {
Toast('删除');
},
},
};
```
## API
### Props
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| contact-info | 联系人信息 | _Contact_ | `{}` |
| is-edit | 是否为编辑联系人 | _boolean_ | `false` |
| is-saving | 是否显示保存按钮加载动画 | _boolean_ | `false` |
| is-deleting | 是否显示删除按钮加载动画 | _boolean_ | `false` |
| tel-validator | 手机号格式校验函数 | _(tel: string) => boolean_ | - |
| show-set-default `v2.3.0` | 是否显示默认联系人栏 | _boolean_ | `false` |
| set-default-label `v2.3.0` | 默认联系人栏文案 | _string_ | - |
### Events
| 事件名 | 说明 | 回调参数 |
| ------ | ------------------ | ----------------- |
| save | 点击保存按钮时触发 | content:表单内容 |
| delete | 点击删除按钮时触发 | content:表单内容 |
### Contact 数据结构
| 键名 | 说明 | 类型 |
| ---- | ------------ | ------------------ |
| name | 联系人姓名 | _string_ |
| tel | 联系人手机号 | _number \| string_ |
+50
View File
@@ -0,0 +1,50 @@
<template>
<demo-section>
<demo-block :title="t('basicUsage')">
<van-contact-edit
is-edit
show-set-default
:contact-info="editingContact"
:set-default-label="t('defaultLabel')"
@save="onSave"
@delete="onDelete"
/>
</demo-block>
</demo-section>
</template>
<script>
export default {
i18n: {
'zh-CN': {
defaultLabel: '设为默认联系人',
},
'en-US': {
defaultLabel: 'Set as the default contact',
},
},
data() {
return {
editingContact: {},
};
},
methods: {
onSave() {
this.$toast(this.t('save'));
},
onDelete() {
this.$toast(this.t('delete'));
},
},
};
</script>
<style lang="less">
.demo-contact-edit {
.van-doc-demo-block__title {
padding-bottom: 0;
}
}
</style>
@@ -0,0 +1,35 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`renders demo correctly 1`] = `
<div>
<div>
<div class="van-contact-edit">
<div class="van-contact-edit__fields">
<div class="van-cell van-field">
<div class="van-cell__title van-field__label"><span>姓名</span></div>
<div class="van-cell__value van-field__value">
<div class="van-field__body"><input type="text" placeholder="请填写姓名" class="van-field__control"></div>
</div>
</div>
<div class="van-cell van-field">
<div class="van-cell__title van-field__label"><span>电话</span></div>
<div class="van-cell__value van-field__value">
<div class="van-field__body"><input type="tel" placeholder="请填写电话" class="van-field__control"></div>
</div>
</div>
</div>
<div class="van-cell van-cell--borderless van-contact-edit__switch-cell">
<div class="van-cell__title"><span>设为默认联系人</span></div>
<div role="switch" aria-checked="false" class="van-switch" style="font-size: 24px;">
<div class="van-switch__node"></div>
</div>
</div>
<div class="van-contact-edit__buttons"><button class="van-button van-button--danger van-button--normal van-button--block van-button--round">
<div class="van-button__content"><span class="van-button__text">保存</span></div>
</button><button class="van-button van-button--default van-button--normal van-button--block van-button--round">
<div class="van-button__content"><span class="van-button__text">删除</span></div>
</button></div>
</div>
</div>
</div>
`;
+4
View File
@@ -0,0 +1,4 @@
import Demo from '../demo';
import { snapshotDemo } from '../../../test/demo';
snapshotDemo(Demo);
+77
View File
@@ -0,0 +1,77 @@
import ContactEdit from '..';
import { mount, later } from '../../../test';
const contactInfo = {
name: 'test',
tel: '123123213',
};
const createComponent = () => {
const wrapper = mount(ContactEdit, {
propsData: {
contactInfo,
},
});
const button = wrapper.find('.van-button');
const field = wrapper.findAll('.van-field__control');
const { errorInfo, data } = wrapper.vm;
return {
wrapper,
data,
field,
button,
errorInfo,
};
};
test('should validate contact name before submit form', () => {
const { data, field, button, errorInfo } = createComponent();
// name empty
data.name = '';
button.trigger('click');
expect(errorInfo.name).toBeTruthy();
field.at(0).trigger('focus');
expect(errorInfo.name).toBeFalsy();
});
test('should validate contact tel before submit form', () => {
const { data, field, button, errorInfo, wrapper } = createComponent();
data.tel = '';
button.trigger('click');
expect(errorInfo.tel).toBeTruthy();
field.at(1).trigger('focus');
expect(errorInfo.tel).toBeFalsy();
data.tel = '13000000000';
button.trigger('click');
expect(errorInfo.tel).toBeFalsy();
expect(wrapper.emitted('save')[0][0]).toEqual({
name: 'test',
tel: '13000000000',
});
});
test('should watch contact info', () => {
const wrapper = mount(ContactEdit);
wrapper.setProps({ contactInfo: { name: '123' } });
expect(wrapper.vm.data.name).toEqual('123');
});
test('should allow deleting contact', async () => {
const wrapper = mount(ContactEdit, {
propsData: {
isEdit: true,
},
});
const deleteButton = wrapper.findAll('.van-button').at(1);
deleteButton.trigger('click');
await later();
document.querySelector('.van-dialog__confirm').click();
await later();
expect(wrapper.emitted('delete')).toBeTruthy();
});