Merge branch 'dev' into next
This commit is contained in:
+64
-55
@@ -2,7 +2,7 @@
|
||||
|
||||
### Install
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
import Vue from 'vue';
|
||||
import { ActionSheet } from 'vant';
|
||||
|
||||
@@ -13,13 +13,15 @@ Vue.use(ActionSheet);
|
||||
|
||||
### Basic Usage
|
||||
|
||||
Use `actions` prop to set options of action-sheet.
|
||||
Use `actions` prop to set options of action-sheet.
|
||||
|
||||
```html
|
||||
<van-action-sheet v-model="show" :actions="actions" @select="onSelect" />
|
||||
```
|
||||
|
||||
```javascript
|
||||
```js
|
||||
import { Toast } from 'vant';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
@@ -31,38 +33,51 @@ export default {
|
||||
]
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
onSelect(item) {
|
||||
this.show = false;
|
||||
Toast(item.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### Status
|
||||
### Show Cancel Button
|
||||
|
||||
```html
|
||||
<van-action-sheet v-model="show" :actions="actions" />
|
||||
<van-action-sheet
|
||||
v-model="show"
|
||||
:actions="actions"
|
||||
cancel-text="Cancel"
|
||||
@cancel="onCancel"
|
||||
/>
|
||||
```
|
||||
|
||||
```javascript
|
||||
```js
|
||||
import { Toast } from 'vant';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
show: false,
|
||||
actions: [
|
||||
{ name: 'Option', color: '#07c160' },
|
||||
{ loading: true },
|
||||
{ name: 'Disabled Option', disabled: true }
|
||||
]
|
||||
show: false
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
onCancel() {
|
||||
this.show = false;
|
||||
Toast('cancel');
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### ActionSheet with cancel button
|
||||
### Show Description
|
||||
|
||||
```html
|
||||
<van-action-sheet v-model="show" :actions="actions" description="Description" />
|
||||
```
|
||||
|
||||
### Option Status
|
||||
|
||||
```html
|
||||
<van-action-sheet
|
||||
@@ -77,35 +92,29 @@ export default {
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
show: false
|
||||
show: false,
|
||||
actions: [
|
||||
{ name: 'Option', color: '#07c160' },
|
||||
{ loading: true },
|
||||
{ name: 'Disabled Option', disabled: true }
|
||||
]
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
onCancel() {
|
||||
this.show = false;
|
||||
Toast('cancel');
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### Show Description
|
||||
|
||||
```html
|
||||
<van-action-sheet
|
||||
v-model="show"
|
||||
:actions="actions"
|
||||
description="Description"
|
||||
/>
|
||||
```
|
||||
|
||||
### ActionSheet with title
|
||||
### Custom Panel
|
||||
|
||||
```html
|
||||
<van-action-sheet v-model="show" title="Title">
|
||||
<p>Content</p>
|
||||
<div class="content">Content</div>
|
||||
</van-action-sheet>
|
||||
|
||||
<style>
|
||||
.content {
|
||||
padding: 16px 16px 160px;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
## API
|
||||
@@ -114,20 +123,31 @@ export default {
|
||||
|
||||
| Attribute | Description | Type | Default |
|
||||
|------|------|------|------|
|
||||
| actions | Options | *Action[]* | `[]` |
|
||||
| actions | Options | *Action[]* | `[]` |
|
||||
| title | Title | *string* | - |
|
||||
| cancel-text | Text of cancel button | *string* | - |
|
||||
| description `v2.2.8` | Description above the options | *string* | - |
|
||||
| overlay | Whether to show overlay | *boolean* | `true` |
|
||||
| round `v2.0.9` | Whether to show round corner | *boolean* | `true` |
|
||||
| close-icon `v2.2.13` | Close icon name | *string* | `cross` |
|
||||
| duration `v2.0.3` | Transition duration, unit second | *number \| string* | `0.3` |
|
||||
| round `v2.0.9` | Whether to show round corner | *boolean* | `true` |
|
||||
| overlay | Whether to show overlay | *boolean* | `true` |
|
||||
| lock-scroll | Whether to lock background scroll | *boolean* | `true` |
|
||||
| lazy-render | Whether to lazy render util appeared | *boolean* | `true` |
|
||||
| close-on-click-action | Whether to close when click action | *boolean* | `false` |
|
||||
| close-on-click-overlay | Whether to close when click overlay | *boolean* | `true` |
|
||||
| lazy-render | Whether to lazy render util appeared | *boolean* | `true` |
|
||||
| lock-scroll | Whether to lock background scroll | *boolean* | `true` |
|
||||
| duration `v2.0.3` | Transition duration, unit second | *number* | `0.3` |
|
||||
| get-container | Return the mount node for action-sheet | *string \| () => Element* | - |
|
||||
| safe-area-inset-bottom | Whether to enable bottom safe area adaptation | *boolean* | `true` |
|
||||
| get-container | Return the mount node for ActionSheet | *string \| () => Element* | - |
|
||||
|
||||
### Data Structure of Action
|
||||
|
||||
| Key | Description | Type |
|
||||
|------|------|------|
|
||||
| name | Title | *string* |
|
||||
| subname | Subtitle | *string* |
|
||||
| color | Text color | *string* |
|
||||
| className | className for the option | *any* |
|
||||
| loading | Whether to be loading status | *boolean* |
|
||||
| disabled | Whether to be disabled | *boolean* |
|
||||
|
||||
### Events
|
||||
|
||||
@@ -140,14 +160,3 @@ export default {
|
||||
| opened | Triggered when opened ActionSheet | - |
|
||||
| close | Triggered when close ActionSheet | - |
|
||||
| closed | Triggered when closed ActionSheet | - |
|
||||
|
||||
### Data Structure of Action
|
||||
|
||||
| Key | Description | Type |
|
||||
|------|------|------|
|
||||
| name | Title | *string* |
|
||||
| subname | Subtitle | *string* |
|
||||
| color | Text color | *string* |
|
||||
| className | className for the option | *any* |
|
||||
| loading | Whether to be loading status | *boolean* |
|
||||
| disabled | Whether to be disabled | *boolean* |
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
### 引入
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
import Vue from 'vue';
|
||||
import { ActionSheet } from 'vant';
|
||||
|
||||
@@ -19,7 +19,9 @@ Vue.use(ActionSheet);
|
||||
<van-action-sheet v-model="show" :actions="actions" @select="onSelect" />
|
||||
```
|
||||
|
||||
```javascript
|
||||
```js
|
||||
import { Toast } from 'vant';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
@@ -31,11 +33,10 @@ export default {
|
||||
]
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
onSelect(item) {
|
||||
// 默认情况下,点击选项时不会自动关闭菜单
|
||||
// 可以通过 close-on-click-action 属性开启自动关闭
|
||||
// 默认情况下点击选项时不会自动收起
|
||||
// 可以通过 close-on-click-action 属性开启自动收起
|
||||
this.show = false;
|
||||
Toast(item.name);
|
||||
}
|
||||
@@ -43,29 +44,6 @@ export default {
|
||||
}
|
||||
```
|
||||
|
||||
### 选项状态
|
||||
|
||||
选项可以设置为加载状态或禁用状态,也可以通过`color`设置选项颜色
|
||||
|
||||
```html
|
||||
<van-action-sheet v-model="show" :actions="actions" />
|
||||
```
|
||||
|
||||
```javascript
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
show: false,
|
||||
actions: [
|
||||
{ name: '选项', color: '#07c160' },
|
||||
{ loading: true },
|
||||
{ name: '禁用选项', disabled: true }
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 展示取消按钮
|
||||
|
||||
设置`cancel-text`属性后,会在底部展示取消按钮,点击后关闭当前菜单
|
||||
@@ -80,13 +58,14 @@ export default {
|
||||
```
|
||||
|
||||
```js
|
||||
import { Toast } from 'vant';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
show: false
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
onCancel() {
|
||||
this.show = false;
|
||||
@@ -108,14 +87,48 @@ export default {
|
||||
/>
|
||||
```
|
||||
|
||||
### 展示标题栏
|
||||
### 选项状态
|
||||
|
||||
通过设置`title`属性展示标题栏,同时可以使用插槽自定义菜单内容
|
||||
可以将选项设置为加载状态或禁用状态,或者通过`color`设置选项颜色
|
||||
|
||||
```html
|
||||
<van-action-sheet
|
||||
v-model="show"
|
||||
:actions="actions"
|
||||
cancel-text="取消"
|
||||
@cancel="onCancel"
|
||||
/>
|
||||
```
|
||||
|
||||
```js
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
show: false,
|
||||
actions: [
|
||||
{ name: '选项', color: '#07c160' },
|
||||
{ loading: true },
|
||||
{ name: '禁用选项', disabled: true }
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 自定义面板
|
||||
|
||||
通过插槽可以自定义菜单的展示内容,同时可以使用`title`属性展示标题栏
|
||||
|
||||
```html
|
||||
<van-action-sheet v-model="show" title="标题">
|
||||
<p>内容</p>
|
||||
<div class="content">内容</div>
|
||||
</van-action-sheet>
|
||||
|
||||
<style>
|
||||
.content {
|
||||
padding: 16px 16px 160px;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
## API
|
||||
@@ -128,28 +141,16 @@ export default {
|
||||
| title | 顶部标题 | *string* | - |
|
||||
| cancel-text | 取消按钮文字 | *string* | - |
|
||||
| description `v2.2.8` | 选项上方的描述信息 | *string* | - |
|
||||
| overlay | 是否显示遮罩层 | *boolean* | `true` |
|
||||
| close-icon `v2.2.13` | 关闭 [图标名称](#/zh-CN/icon) 或图片链接 | *string* | `cross` |
|
||||
| duration `v2.0.3` | 动画时长,单位秒 | *number \| string* | `0.3` |
|
||||
| round `v2.0.9` | 是否显示圆角 | *boolean* | `true` |
|
||||
| close-icon `v2.2.13` | 关闭图标名称或图片链接 | *string* | `cross` |
|
||||
| overlay | 是否显示遮罩层 | *boolean* | `true` |
|
||||
| lock-scroll | 是否锁定背景滚动 | *boolean* | `true` |
|
||||
| lazy-render | 是否在显示弹层时才渲染节点 | *boolean* | `true` |
|
||||
| close-on-click-action | 是否在点击选项后关闭 | *boolean* | `false` |
|
||||
| close-on-click-overlay | 是否在点击遮罩层后关闭 | *boolean* | `true` |
|
||||
| lazy-render | 是否在显示弹层时才渲染节点 | *boolean* | `true` |
|
||||
| lock-scroll | 是否锁定背景滚动 | *boolean* | `true` |
|
||||
| duration `v2.0.3` | 动画时长,单位秒 | *number* | `0.3` |
|
||||
| safe-area-inset-bottom | 是否开启 [底部安全区适配](#/zh-CN/quickstart#di-bu-an-quan-qu-gua-pei) | *boolean* | `true` |
|
||||
| get-container | 指定挂载的节点,[用法示例](#/zh-CN/popup#zhi-ding-gua-zai-wei-zhi) | *string \| () => Element* | - |
|
||||
| safe-area-inset-bottom | 是否开启底部安全区适配,[详细说明](#/zh-CN/quickstart#di-bu-an-quan-qu-gua-pei) | *boolean* | `true` |
|
||||
|
||||
### Events
|
||||
|
||||
| 事件名 | 说明 | 回调参数 |
|
||||
|------|------|------|
|
||||
| select | 选中选项时触发,禁用或加载状态下不会触发 | item: 选项对应的对象, index: 选择对应的索引 |
|
||||
| cancel | 取消按钮点击时触发 | - |
|
||||
| click-overlay | 点击遮罩层时触发 | - |
|
||||
| open | 打开菜单时触发 | - |
|
||||
| opened | 打开菜单且动画结束后触发 | - |
|
||||
| close | 关闭菜单时触发 | - |
|
||||
| closed | 关闭菜单且动画结束后触发 | - |
|
||||
|
||||
### Action 数据结构
|
||||
|
||||
@@ -164,6 +165,18 @@ export default {
|
||||
| loading | 是否为加载状态 | *boolean* |
|
||||
| disabled | 是否为禁用状态 | *boolean* |
|
||||
|
||||
### Events
|
||||
|
||||
| 事件名 | 说明 | 回调参数 |
|
||||
|------|------|------|
|
||||
| select | 选中选项时触发,禁用或加载状态下不会触发 | item: 选项对应的对象, index: 选择对应的索引 |
|
||||
| cancel | 取消按钮点击时触发 | - |
|
||||
| click-overlay | 点击遮罩层时触发 | - |
|
||||
| open | 打开菜单时触发 | - |
|
||||
| opened | 打开菜单且动画结束后触发 | - |
|
||||
| close | 关闭菜单时触发 | - |
|
||||
| closed | 关闭菜单且动画结束后触发 | - |
|
||||
|
||||
## 常见问题
|
||||
|
||||
### 引入时提示 dependencies not found?
|
||||
|
||||
@@ -1,42 +1,58 @@
|
||||
<template>
|
||||
<demo-section>
|
||||
<demo-block :title="$t('basicUsage')">
|
||||
<van-button type="primary" @click="show1 = true">{{ $t('buttonText') }}</van-button>
|
||||
<van-action-sheet v-model="show1" :actions="simpleActions" @select="onSelect" />
|
||||
</demo-block>
|
||||
|
||||
<demo-block :title="$t('status')">
|
||||
<van-button type="primary" @click="show2 = true">{{ $t('buttonText') }}</van-button>
|
||||
<van-action-sheet v-model="show2" close-on-click-action :actions="statusActions" />
|
||||
</demo-block>
|
||||
|
||||
<demo-block :title="$t('showCancel')">
|
||||
<van-button type="primary" @click="show3 = true">{{ $t('buttonText') }}</van-button>
|
||||
<van-action-sheet
|
||||
v-model="show3"
|
||||
:actions="simpleActions"
|
||||
close-on-click-action
|
||||
:cancel-text="$t('cancel')"
|
||||
@cancel="onCancel"
|
||||
<van-cell is-link :title="$t('basicUsage')" @click="show.basic = true" />
|
||||
<van-cell is-link :title="$t('showCancel')" @click="show.cancel = true" />
|
||||
<van-cell
|
||||
is-link
|
||||
:title="$t('showDescription')"
|
||||
@click="show.description = true"
|
||||
/>
|
||||
</demo-block>
|
||||
|
||||
<demo-block :title="$t('showDescription')">
|
||||
<van-button type="primary" @click="show4 = true">{{ $t('buttonText') }}</van-button>
|
||||
<van-action-sheet
|
||||
v-model="show4"
|
||||
:actions="simpleActions"
|
||||
close-on-click-action
|
||||
:description="$t('description')"
|
||||
<demo-block :title="$t('optionStatus')">
|
||||
<van-cell
|
||||
is-link
|
||||
:title="$t('optionStatus')"
|
||||
@click="show.status = true"
|
||||
/>
|
||||
</demo-block>
|
||||
|
||||
<demo-block :title="$t('showTitle')">
|
||||
<van-button type="primary" @click="show5 = true">{{ $t('buttonText') }}</van-button>
|
||||
<van-action-sheet v-model="show5" :title="$t('title')">
|
||||
<p>{{ $t('content') }}</p>
|
||||
</van-action-sheet>
|
||||
<demo-block :title="$t('customPanel')">
|
||||
<van-cell is-link :title="$t('customPanel')" @click="show.title = true" />
|
||||
</demo-block>
|
||||
|
||||
<van-action-sheet
|
||||
v-model="show.basic"
|
||||
:actions="simpleActions"
|
||||
@select="onSelect"
|
||||
/>
|
||||
|
||||
<van-action-sheet
|
||||
v-model="show.status"
|
||||
close-on-click-action
|
||||
:actions="statusActions"
|
||||
:cancel-text="$t('cancel')"
|
||||
/>
|
||||
|
||||
<van-action-sheet
|
||||
v-model="show.cancel"
|
||||
:actions="simpleActions"
|
||||
close-on-click-action
|
||||
:cancel-text="$t('cancel')"
|
||||
@cancel="onCancel"
|
||||
/>
|
||||
|
||||
<van-action-sheet
|
||||
v-model="show.description"
|
||||
:actions="simpleActions"
|
||||
close-on-click-action
|
||||
:description="$t('description')"
|
||||
/>
|
||||
|
||||
<van-action-sheet v-model="show.title" :title="$t('title')">
|
||||
<div class="demo-action-sheet-content">{{ $t('content') }}</div>
|
||||
</van-action-sheet>
|
||||
</demo-section>
|
||||
</template>
|
||||
|
||||
@@ -46,34 +62,36 @@ import { GREEN } from '../../utils/constant';
|
||||
export default {
|
||||
i18n: {
|
||||
'zh-CN': {
|
||||
buttonText: '弹出菜单',
|
||||
status: '选项状态',
|
||||
subname: '副文本',
|
||||
disabledOption: '禁用选项',
|
||||
showTitle: '展示标题栏',
|
||||
showCancel: '展示取消按钮',
|
||||
buttonText: '弹出菜单',
|
||||
customPanel: '自定义面板',
|
||||
description: '这是一段描述信息',
|
||||
optionStatus: '选项状态',
|
||||
disabledOption: '禁用选项',
|
||||
showDescription: '展示描述信息',
|
||||
description: '这是一段描述信息'
|
||||
},
|
||||
'en-US': {
|
||||
buttonText: 'Show ActionSheet',
|
||||
status: 'Status',
|
||||
subname: 'Subname',
|
||||
showCancel: 'Show Cancel Button',
|
||||
buttonText: 'Show ActionSheet',
|
||||
customPanel: 'Custom Panel',
|
||||
description: 'Description',
|
||||
optionStatus: 'Option Status',
|
||||
disabledOption: 'Disabled Option',
|
||||
showTitle: 'ActionSheet with title',
|
||||
showCancel: 'ActionSheet with cancel button',
|
||||
showDescription: 'ActionSheet with description',
|
||||
description: 'Description'
|
||||
}
|
||||
showDescription: 'Show Description',
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
show1: false,
|
||||
show2: false,
|
||||
show3: false,
|
||||
show4: false,
|
||||
show5: false
|
||||
show: {
|
||||
basic: false,
|
||||
cancel: false,
|
||||
title: false,
|
||||
status: false,
|
||||
description: false,
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
@@ -82,7 +100,7 @@ export default {
|
||||
return [
|
||||
{ name: this.$t('option') },
|
||||
{ name: this.$t('option') },
|
||||
{ name: this.$t('option'), subname: this.$t('subname') }
|
||||
{ name: this.$t('option'), subname: this.$t('subname') },
|
||||
];
|
||||
},
|
||||
|
||||
@@ -90,21 +108,21 @@ export default {
|
||||
return [
|
||||
{ name: this.$t('option'), color: GREEN },
|
||||
{ loading: true },
|
||||
{ name: this.$t('disabledOption'), disabled: true }
|
||||
{ name: this.$t('disabledOption'), disabled: true },
|
||||
];
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
onSelect(item) {
|
||||
this.show1 = false;
|
||||
this.show.basic = false;
|
||||
this.$toast(item.name);
|
||||
},
|
||||
|
||||
onCancel() {
|
||||
this.$toast('cancel');
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -112,13 +130,7 @@ export default {
|
||||
@import '../../style/var';
|
||||
|
||||
.demo-action-sheet {
|
||||
background-color: @white;
|
||||
|
||||
.van-button {
|
||||
margin-left: @padding-md;
|
||||
}
|
||||
|
||||
p {
|
||||
&-content {
|
||||
padding: @padding-md @padding-md @padding-md * 10;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
// Utils
|
||||
import { createNamespace } from '../utils';
|
||||
import { emit, inherit } from '../utils/functional';
|
||||
import { BORDER_TOP } from '../utils/constant';
|
||||
|
||||
// Mixins
|
||||
import { popupMixinProps } from '../mixins/popup';
|
||||
|
||||
// Components
|
||||
import Icon from '../icon';
|
||||
import Popup from '../popup';
|
||||
import Loading from '../loading';
|
||||
@@ -25,7 +30,7 @@ export type ActionSheetProps = PopupMixinProps & {
|
||||
round: boolean;
|
||||
title?: string;
|
||||
actions?: ActionSheetItem[];
|
||||
duration: number;
|
||||
duration: number | string;
|
||||
closeIcon: string;
|
||||
cancelText?: string;
|
||||
description?: string;
|
||||
@@ -97,7 +102,7 @@ function ActionSheet(
|
||||
|
||||
return [
|
||||
<span class={bem('name')}>{item.name}</span>,
|
||||
item.subname && <span class={bem('subname')}>{item.subname}</span>
|
||||
item.subname && <span class={bem('subname')}>{item.subname}</span>,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -155,31 +160,31 @@ ActionSheet.props = {
|
||||
...popupMixinProps,
|
||||
title: String,
|
||||
actions: Array,
|
||||
duration: Number,
|
||||
duration: [Number, String],
|
||||
cancelText: String,
|
||||
description: String,
|
||||
getContainer: [String, Function],
|
||||
closeOnClickAction: Boolean,
|
||||
round: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
default: true,
|
||||
},
|
||||
closeIcon: {
|
||||
type: String,
|
||||
default: 'cross'
|
||||
default: 'cross',
|
||||
},
|
||||
safeAreaInsetBottom: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
default: true,
|
||||
},
|
||||
overlay: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
default: true,
|
||||
},
|
||||
closeOnClickOverlay: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
default: true,
|
||||
},
|
||||
};
|
||||
|
||||
export default createComponent<ActionSheetProps>(ActionSheet);
|
||||
|
||||
@@ -2,20 +2,36 @@
|
||||
|
||||
exports[`renders demo correctly 1`] = `
|
||||
<div>
|
||||
<div><button class="van-button van-button--primary van-button--normal"><span class="van-button__text">弹出菜单</span></button>
|
||||
<!---->
|
||||
<div>
|
||||
<div role="button" tabindex="0" class="van-cell van-cell--clickable">
|
||||
<div class="van-cell__title"><span>基础用法</span></div><i class="van-icon van-icon-arrow van-cell__right-icon">
|
||||
<!----></i>
|
||||
</div>
|
||||
<div role="button" tabindex="0" class="van-cell van-cell--clickable">
|
||||
<div class="van-cell__title"><span>展示取消按钮</span></div><i class="van-icon van-icon-arrow van-cell__right-icon">
|
||||
<!----></i>
|
||||
</div>
|
||||
<div role="button" tabindex="0" class="van-cell van-cell--clickable">
|
||||
<div class="van-cell__title"><span>展示描述信息</span></div><i class="van-icon van-icon-arrow van-cell__right-icon">
|
||||
<!----></i>
|
||||
</div>
|
||||
</div>
|
||||
<div><button class="van-button van-button--primary van-button--normal"><span class="van-button__text">弹出菜单</span></button>
|
||||
<!---->
|
||||
<div>
|
||||
<div role="button" tabindex="0" class="van-cell van-cell--clickable">
|
||||
<div class="van-cell__title"><span>选项状态</span></div><i class="van-icon van-icon-arrow van-cell__right-icon">
|
||||
<!----></i>
|
||||
</div>
|
||||
</div>
|
||||
<div><button class="van-button van-button--primary van-button--normal"><span class="van-button__text">弹出菜单</span></button>
|
||||
<!---->
|
||||
</div>
|
||||
<div><button class="van-button van-button--primary van-button--normal"><span class="van-button__text">弹出菜单</span></button>
|
||||
<!---->
|
||||
</div>
|
||||
<div><button class="van-button van-button--primary van-button--normal"><span class="van-button__text">弹出菜单</span></button>
|
||||
<!---->
|
||||
<div>
|
||||
<div role="button" tabindex="0" class="van-cell van-cell--clickable">
|
||||
<div class="van-cell__title"><span>自定义面板</span></div><i class="van-icon van-icon-arrow van-cell__right-icon">
|
||||
<!----></i>
|
||||
</div>
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
<!---->
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -18,15 +18,15 @@ test('callback events', () => {
|
||||
propsData: {
|
||||
value: true,
|
||||
actions,
|
||||
cancelText: 'Cancel'
|
||||
cancelText: 'Cancel',
|
||||
},
|
||||
context: {
|
||||
on: {
|
||||
input: onInput,
|
||||
cancel: onCancel,
|
||||
select: onSelect
|
||||
}
|
||||
}
|
||||
select: onSelect,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const options = wrapper.findAll('.van-action-sheet__item');
|
||||
@@ -58,17 +58,17 @@ test('click overlay and close', async () => {
|
||||
</div>
|
||||
`,
|
||||
components: {
|
||||
ActionSheet
|
||||
ActionSheet,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
getContainer: () => div
|
||||
getContainer: () => div,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
onInput,
|
||||
onClickOverlay
|
||||
}
|
||||
onClickOverlay,
|
||||
},
|
||||
});
|
||||
|
||||
await later();
|
||||
@@ -82,12 +82,9 @@ test('disable lazy-render', () => {
|
||||
const wrapper = mount(ActionSheet, {
|
||||
propsData: {
|
||||
lazyRender: false,
|
||||
actions: [
|
||||
{ name: 'Option' },
|
||||
{ name: 'Option' }
|
||||
],
|
||||
cancelText: 'Cancel'
|
||||
}
|
||||
actions: [{ name: 'Option' }, { name: 'Option' }],
|
||||
cancelText: 'Cancel',
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
@@ -97,13 +94,13 @@ test('render title and default slot', () => {
|
||||
const wrapper = mount(ActionSheet, {
|
||||
propsData: {
|
||||
value: true,
|
||||
title: 'Title'
|
||||
title: 'Title',
|
||||
},
|
||||
scopedSlots: {
|
||||
default() {
|
||||
return 'Default';
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
@@ -113,8 +110,8 @@ test('get container', () => {
|
||||
const wrapper = mount(ActionSheet, {
|
||||
propsData: {
|
||||
value: true,
|
||||
getContainer: 'body'
|
||||
}
|
||||
getContainer: 'body',
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper.vm.$el.parentNode).toEqual(document.body);
|
||||
@@ -126,13 +123,13 @@ test('close-on-click-action prop', () => {
|
||||
propsData: {
|
||||
value: true,
|
||||
actions: [{ name: 'Option' }],
|
||||
closeOnClickAction: true
|
||||
closeOnClickAction: true,
|
||||
},
|
||||
context: {
|
||||
on: {
|
||||
input: onInput
|
||||
}
|
||||
}
|
||||
input: onInput,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const option = wrapper.find('.van-action-sheet__item');
|
||||
@@ -146,8 +143,8 @@ test('round prop', () => {
|
||||
propsData: {
|
||||
value: true,
|
||||
round: true,
|
||||
actions: [{ name: 'Option' }]
|
||||
}
|
||||
actions: [{ name: 'Option' }],
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
@@ -157,8 +154,8 @@ test('color option', () => {
|
||||
const wrapper = mount(ActionSheet, {
|
||||
propsData: {
|
||||
value: true,
|
||||
actions: [{ name: 'Option', color: 'red' }]
|
||||
}
|
||||
actions: [{ name: 'Option', color: 'red' }],
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
@@ -169,8 +166,8 @@ test('description prop', () => {
|
||||
propsData: {
|
||||
value: true,
|
||||
description: 'This is a description',
|
||||
actions: [{ name: 'Option' }]
|
||||
}
|
||||
actions: [{ name: 'Option' }],
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
@@ -181,8 +178,8 @@ test('close-icon prop', () => {
|
||||
propsData: {
|
||||
value: true,
|
||||
title: 'Title',
|
||||
closeIcon: 'cross'
|
||||
}
|
||||
closeIcon: 'cross',
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
// Utils
|
||||
import { createNamespace } from '../utils';
|
||||
import { isAndroid } from '../utils/validate/system';
|
||||
|
||||
// Components
|
||||
import Cell from '../cell';
|
||||
import Field from '../field';
|
||||
|
||||
@@ -11,16 +14,16 @@ export default createComponent({
|
||||
value: String,
|
||||
errorMessage: String,
|
||||
focused: Boolean,
|
||||
detailRows: Number,
|
||||
detailRows: [Number, String],
|
||||
searchResult: Array,
|
||||
detailMaxlength: Number,
|
||||
showSearchResult: Boolean
|
||||
detailMaxlength: [Number, String],
|
||||
showSearchResult: Boolean,
|
||||
},
|
||||
|
||||
computed: {
|
||||
shouldShowSearchResult() {
|
||||
return this.focused && this.searchResult && this.showSearchResult;
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
@@ -71,12 +74,12 @@ export default createComponent({
|
||||
|
||||
return <div domPropsInnerHTML={text} />;
|
||||
}
|
||||
}
|
||||
},
|
||||
}}
|
||||
/>
|
||||
));
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
render() {
|
||||
@@ -100,5 +103,5 @@ export default createComponent({
|
||||
{this.genSearchResult()}
|
||||
</Cell>
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
### Install
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
import Vue from 'vue';
|
||||
import { AddressEdit } from 'vant';
|
||||
|
||||
@@ -28,7 +28,9 @@ Vue.use(AddressEdit);
|
||||
/>
|
||||
```
|
||||
|
||||
```javascript
|
||||
```js
|
||||
import { Toast } from 'vant';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
@@ -36,7 +38,6 @@ export default {
|
||||
searchResult: []
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
onSave() {
|
||||
Toast('save');
|
||||
@@ -74,13 +75,13 @@ export default {
|
||||
| show-search-result | Whether to show address search result | *boolean* | `false` |
|
||||
| save-button-text | Save button text | *string* | `Save` |
|
||||
| delete-button-text | Delete button text | *string* | `Delete` |
|
||||
| detail-rows | Detail input rows | *number* | `1` |
|
||||
| detail-maxlength `v2.0.4` | Detail maxlength | *number* | `200` |
|
||||
| detail-rows | Detail input rows | *number \| string* | `1` |
|
||||
| detail-maxlength `v2.0.4` | Detail maxlength | *number \| string* | `200` |
|
||||
| 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* | - |
|
||||
| postal-validator `v2.1.2` | The method to validate postal | *(tel: string) => boolean* | - |
|
||||
| validator | Custom validator | *(key, value) => string* | - |
|
||||
| validator | Custom validator | *(key, val) => string* | - |
|
||||
|
||||
### Events
|
||||
|
||||
@@ -113,7 +114,7 @@ Use [ref](https://vuejs.org/v2/api/#ref) to get AddressEdit instance and call in
|
||||
|
||||
| key | Description | Type |
|
||||
|------|------|------|
|
||||
| id | Address Id | *string \| number* |
|
||||
| id | Address Id | *number \| string* |
|
||||
| name | Name | *string* |
|
||||
| tel | Phone | *string* |
|
||||
| province | Province | *string* |
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
### 引入
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
import Vue from 'vue';
|
||||
import { AddressEdit } from 'vant';
|
||||
|
||||
@@ -28,7 +28,9 @@ Vue.use(AddressEdit);
|
||||
/>
|
||||
```
|
||||
|
||||
```javascript
|
||||
```js
|
||||
import { Toast } from 'vant';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
@@ -36,7 +38,6 @@ export default {
|
||||
searchResult: []
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
onSave() {
|
||||
Toast('save');
|
||||
@@ -74,13 +75,13 @@ export default {
|
||||
| show-search-result | 是否显示搜索结果 | *boolean* | `false` |
|
||||
| save-button-text | 保存按钮文字 | *string* | `保存` |
|
||||
| delete-button-text | 删除按钮文字 | *string* | `删除` |
|
||||
| detail-rows | 详细地址输入框行数 | *number* | `1` |
|
||||
| detail-maxlength `v2.0.4` | 详细地址最大长度 | *number* | `200` |
|
||||
| detail-rows | 详细地址输入框行数 | *number \| string* | `1` |
|
||||
| detail-maxlength `v2.0.4` | 详细地址最大长度 | *number \| string* | `200` |
|
||||
| is-saving | 是否显示保存按钮加载动画 | *boolean* | `false` |
|
||||
| is-deleting | 是否显示删除按钮加载动画 | *boolean* | `false` |
|
||||
| tel-validator | 手机号格式校验函数 | *string => boolean* | - |
|
||||
| postal-validator `v2.1.2` | 邮政编码格式校验函数 | *string => boolean* | - |
|
||||
| validator | 自定义校验函数 | *(key, value) => string* | - |
|
||||
| validator | 自定义校验函数 | *(key, val) => string* | - |
|
||||
|
||||
### Events
|
||||
|
||||
@@ -103,7 +104,7 @@ export default {
|
||||
|
||||
### 方法
|
||||
|
||||
通过 [ref](https://cn.vuejs.org/v2/api/#ref) 可以获取到 AddressEdit 实例并调用实例方法
|
||||
通过 ref 可以获取到 AddressEdit 实例并调用实例方法,详见 [组件实例方法](#/zh-CN/quickstart#zu-jian-shi-li-fang-fa)
|
||||
|
||||
| 方法名 | 说明 | 参数 | 返回值 |
|
||||
|------|------|------|------|
|
||||
@@ -115,7 +116,7 @@ export default {
|
||||
|
||||
| key | 说明 | 类型 |
|
||||
|------|------|------|
|
||||
| id | 每条地址的唯一标识 | *string \| number* |
|
||||
| id | 每条地址的唯一标识 | *number \| string* |
|
||||
| name | 收货人姓名 | *string* |
|
||||
| tel | 收货人手机号 | *string* |
|
||||
| province | 省份 | *string* |
|
||||
|
||||
@@ -24,34 +24,42 @@ export default {
|
||||
i18n: {
|
||||
'zh-CN': {
|
||||
areaColumnsPlaceholder: ['请选择', '请选择', '请选择'],
|
||||
searchResult: [{
|
||||
name: '黄龙万科中心',
|
||||
address: '杭州市西湖区'
|
||||
}, {
|
||||
name: '黄龙万科中心G座'
|
||||
}, {
|
||||
name: '黄龙万科中心H座',
|
||||
address: '杭州市西湖区'
|
||||
}]
|
||||
searchResult: [
|
||||
{
|
||||
name: '黄龙万科中心',
|
||||
address: '杭州市西湖区',
|
||||
},
|
||||
{
|
||||
name: '黄龙万科中心G座',
|
||||
},
|
||||
{
|
||||
name: '黄龙万科中心H座',
|
||||
address: '杭州市西湖区',
|
||||
},
|
||||
],
|
||||
},
|
||||
'en-US': {
|
||||
areaColumnsPlaceholder: ['Choose', 'Choose', 'Choose'],
|
||||
searchResult: [{
|
||||
name: 'Name1',
|
||||
address: 'Address'
|
||||
}, {
|
||||
name: 'Name2'
|
||||
}, {
|
||||
name: 'Name3',
|
||||
address: 'Address'
|
||||
}]
|
||||
}
|
||||
searchResult: [
|
||||
{
|
||||
name: 'Name1',
|
||||
address: 'Address',
|
||||
},
|
||||
{
|
||||
name: 'Name2',
|
||||
},
|
||||
{
|
||||
name: 'Name3',
|
||||
address: 'Address',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
areaList,
|
||||
searchResult: []
|
||||
searchResult: [],
|
||||
};
|
||||
},
|
||||
|
||||
@@ -66,8 +74,8 @@ export default {
|
||||
|
||||
onChangeDetail(val) {
|
||||
this.searchResult = val ? this.$t('searchResult') : [];
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
+26
-23
@@ -1,5 +1,8 @@
|
||||
import { createNamespace, isObj } from '../utils';
|
||||
// Utils
|
||||
import { createNamespace, isObject } from '../utils';
|
||||
import { isMobile } from '../utils/validate/mobile';
|
||||
|
||||
// Components
|
||||
import Area from '../area';
|
||||
import Field from '../field';
|
||||
import Popup from '../popup';
|
||||
@@ -21,7 +24,7 @@ const defaultData = {
|
||||
areaCode: '',
|
||||
postalCode: '',
|
||||
addressDetail: '',
|
||||
isDefault: false
|
||||
isDefault: false,
|
||||
};
|
||||
|
||||
function isPostal(value) {
|
||||
@@ -43,36 +46,36 @@ export default createComponent({
|
||||
deleteButtonText: String,
|
||||
showArea: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
default: true,
|
||||
},
|
||||
showDetail: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
default: true,
|
||||
},
|
||||
detailRows: {
|
||||
type: Number,
|
||||
default: 1
|
||||
type: [Number, String],
|
||||
default: 1,
|
||||
},
|
||||
detailMaxlength: {
|
||||
type: Number,
|
||||
default: 200
|
||||
type: [Number, String],
|
||||
default: 200,
|
||||
},
|
||||
addressInfo: {
|
||||
type: Object,
|
||||
default: () => ({ ...defaultData })
|
||||
default: () => ({ ...defaultData }),
|
||||
},
|
||||
telValidator: {
|
||||
type: Function,
|
||||
default: isMobile
|
||||
default: isMobile,
|
||||
},
|
||||
postalValidator: {
|
||||
type: Function,
|
||||
default: isPostal
|
||||
default: isPostal,
|
||||
},
|
||||
areaColumnsPlaceholder: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
@@ -85,14 +88,14 @@ export default createComponent({
|
||||
name: '',
|
||||
areaCode: '',
|
||||
postalCode: '',
|
||||
addressDetail: ''
|
||||
}
|
||||
addressDetail: '',
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
areaListLoaded() {
|
||||
return isObj(this.areaList) && Object.keys(this.areaList).length;
|
||||
return isObject(this.areaList) && Object.keys(this.areaList).length;
|
||||
},
|
||||
|
||||
areaText() {
|
||||
@@ -105,7 +108,7 @@ export default createComponent({
|
||||
return arr.filter(text => text).join('/');
|
||||
}
|
||||
return '';
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
watch: {
|
||||
@@ -113,18 +116,18 @@ export default createComponent({
|
||||
handler(val) {
|
||||
this.data = {
|
||||
...defaultData,
|
||||
...val
|
||||
...val,
|
||||
};
|
||||
|
||||
this.setAreaCode(val.areaCode);
|
||||
},
|
||||
deep: true,
|
||||
immediate: true
|
||||
immediate: true,
|
||||
},
|
||||
|
||||
areaList() {
|
||||
this.setAreaCode(this.data.areaCode);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
@@ -209,7 +212,7 @@ export default createComponent({
|
||||
|
||||
onDelete() {
|
||||
Dialog.confirm({
|
||||
title: t('confirmDelete')
|
||||
title: t('confirmDelete'),
|
||||
})
|
||||
.then(() => {
|
||||
this.$emit('delete', this.data);
|
||||
@@ -243,7 +246,7 @@ export default createComponent({
|
||||
setTimeout(() => {
|
||||
this.detailFocused = false;
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
render() {
|
||||
@@ -368,5 +371,5 @@ export default createComponent({
|
||||
</Popup>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -20,7 +20,7 @@ exports[`renders demo correctly 1`] = `
|
||||
<div role="button" tabindex="0" class="van-cell van-cell--clickable van-field">
|
||||
<div class="van-cell__title van-field__label"><span>地区</span></div>
|
||||
<div class="van-cell__value">
|
||||
<div class="van-field__body"><input type="text" placeholder="选择省 / 市 / 区" readonly="readonly" class="van-field__control">
|
||||
<div class="van-field__body"><input type="text" readonly="readonly" placeholder="选择省 / 市 / 区" class="van-field__control">
|
||||
<div class="van-field__right-icon"><i class="van-icon van-icon-arrow">
|
||||
<!----></i></div>
|
||||
</div>
|
||||
|
||||
@@ -18,7 +18,7 @@ exports[`create a AddressEdit 1`] = `
|
||||
<div role="button" tabindex="0" class="van-cell van-cell--clickable van-field">
|
||||
<div class="van-cell__title van-field__label"><span>地区</span></div>
|
||||
<div class="van-cell__value">
|
||||
<div class="van-field__body"><input type="text" placeholder="选择省 / 市 / 区" readonly="readonly" class="van-field__control">
|
||||
<div class="van-field__body"><input type="text" readonly="readonly" placeholder="选择省 / 市 / 区" class="van-field__control">
|
||||
<div class="van-field__right-icon"><i class="van-icon van-icon-arrow">
|
||||
<!----></i></div>
|
||||
</div>
|
||||
@@ -57,7 +57,7 @@ exports[`create a AddressEdit with props 1`] = `
|
||||
<div role="button" tabindex="0" class="van-cell van-cell--clickable van-field">
|
||||
<div class="van-cell__title van-field__label"><span>地区</span></div>
|
||||
<div class="van-cell__value">
|
||||
<div class="van-field__body"><input type="text" placeholder="选择省 / 市 / 区" readonly="readonly" class="van-field__control">
|
||||
<div class="van-field__body"><input type="text" readonly="readonly" placeholder="选择省 / 市 / 区" class="van-field__control">
|
||||
<div class="van-field__right-icon"><i class="van-icon van-icon-arrow">
|
||||
<!----></i></div>
|
||||
</div>
|
||||
@@ -110,7 +110,7 @@ exports[`set-default 1`] = `
|
||||
<div role="button" tabindex="0" class="van-cell van-cell--clickable van-field">
|
||||
<div class="van-cell__title van-field__label"><span>地区</span></div>
|
||||
<div class="van-cell__value">
|
||||
<div class="van-field__body"><input type="text" placeholder="选择省 / 市 / 区" readonly="readonly" class="van-field__control">
|
||||
<div class="van-field__body"><input type="text" readonly="readonly" placeholder="选择省 / 市 / 区" class="van-field__control">
|
||||
<div class="van-field__right-icon"><i class="van-icon van-icon-arrow">
|
||||
<!----></i></div>
|
||||
</div>
|
||||
@@ -163,7 +163,7 @@ exports[`show area component 1`] = `
|
||||
<div role="button" tabindex="0" class="van-cell van-cell--clickable van-field">
|
||||
<div class="van-cell__title van-field__label"><span>地区</span></div>
|
||||
<div class="van-cell__value">
|
||||
<div class="van-field__body"><input type="text" placeholder="选择省 / 市 / 区" readonly="readonly" class="van-field__control">
|
||||
<div class="van-field__body"><input type="text" readonly="readonly" placeholder="选择省 / 市 / 区" class="van-field__control">
|
||||
<div class="van-field__right-icon"><i class="van-icon van-icon-arrow">
|
||||
<!----></i></div>
|
||||
</div>
|
||||
@@ -216,7 +216,7 @@ exports[`show area component 2`] = `
|
||||
<div role="button" tabindex="0" class="van-cell van-cell--clickable van-field">
|
||||
<div class="van-cell__title van-field__label"><span>地区</span></div>
|
||||
<div class="van-cell__value">
|
||||
<div class="van-field__body"><input type="text" placeholder="选择省 / 市 / 区" readonly="readonly" class="van-field__control">
|
||||
<div class="van-field__body"><input type="text" readonly="readonly" placeholder="选择省 / 市 / 区" class="van-field__control">
|
||||
<div class="van-field__right-icon"><i class="van-icon van-icon-arrow">
|
||||
<!----></i></div>
|
||||
</div>
|
||||
@@ -269,7 +269,7 @@ exports[`valid area placeholder confirm 1`] = `
|
||||
<div role="button" tabindex="0" class="van-cell van-cell--clickable van-field">
|
||||
<div class="van-cell__title van-field__label"><span>地区</span></div>
|
||||
<div class="van-cell__value">
|
||||
<div class="van-field__body"><input type="text" placeholder="选择省 / 市 / 区" readonly="readonly" class="van-field__control">
|
||||
<div class="van-field__body"><input type="text" readonly="readonly" placeholder="选择省 / 市 / 区" class="van-field__control">
|
||||
<div class="van-field__right-icon"><i class="van-icon van-icon-arrow">
|
||||
<!----></i></div>
|
||||
</div>
|
||||
|
||||
@@ -11,7 +11,7 @@ const addressInfo = {
|
||||
addressDetail: '详细地址',
|
||||
areaCode: '110101',
|
||||
postalCode: '10000',
|
||||
isDefault: true
|
||||
isDefault: true,
|
||||
};
|
||||
|
||||
const createComponent = () => {
|
||||
@@ -20,8 +20,8 @@ const createComponent = () => {
|
||||
areaList,
|
||||
addressInfo,
|
||||
showPostal: true,
|
||||
showSetDefault: true
|
||||
}
|
||||
showSetDefault: true,
|
||||
},
|
||||
});
|
||||
|
||||
const button = wrapper.find('.van-button');
|
||||
@@ -33,7 +33,7 @@ const createComponent = () => {
|
||||
field,
|
||||
button,
|
||||
wrapper,
|
||||
errorInfo
|
||||
errorInfo,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -48,8 +48,8 @@ test('create a AddressEdit with props', () => {
|
||||
addressInfo,
|
||||
showPostal: true,
|
||||
showSetDefault: true,
|
||||
showSearchResult: true
|
||||
}
|
||||
showSearchResult: true,
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
@@ -60,7 +60,7 @@ test('valid area placeholder confirm', async () => {
|
||||
propsData: {
|
||||
areaList,
|
||||
areaColumnsPlaceholder: ['请选择', '请选择', '请选择'],
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const { data } = wrapper.vm;
|
||||
@@ -100,8 +100,8 @@ test('validator props', async () => {
|
||||
areaList,
|
||||
validator(key, value) {
|
||||
return `${key}${value}`;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const { errorInfo, data } = wrapper.vm;
|
||||
@@ -192,13 +192,13 @@ test('watch address info', () => {
|
||||
|
||||
test('set/get area code', async () => {
|
||||
const wrapper = mount(AddressEdit, {
|
||||
propsData: { areaList }
|
||||
propsData: { areaList },
|
||||
});
|
||||
|
||||
expect(wrapper.vm.getArea()).toEqual([
|
||||
{ code: '110000', name: '北京市' },
|
||||
{ code: '110100', name: '北京市' },
|
||||
{ code: '110101', name: '东城区' }
|
||||
{ code: '110101', name: '东城区' },
|
||||
]);
|
||||
|
||||
wrapper.vm.setAreaCode('110102');
|
||||
@@ -208,7 +208,7 @@ test('set/get area code', async () => {
|
||||
expect(wrapper.vm.getArea()).toEqual([
|
||||
{ code: '110000', name: '北京市' },
|
||||
{ code: '110100', name: '北京市' },
|
||||
{ code: '110102', name: '西城区' }
|
||||
{ code: '110102', name: '西城区' },
|
||||
]);
|
||||
|
||||
wrapper.vm.$refs = [];
|
||||
@@ -221,9 +221,9 @@ test('watch area code', async () => {
|
||||
propsData: {
|
||||
areaList: {},
|
||||
addressInfo: {
|
||||
areaCode: '110101'
|
||||
}
|
||||
}
|
||||
areaCode: '110101',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper.vm.data.city).toEqual('');
|
||||
@@ -240,9 +240,9 @@ test('show search result', async () => {
|
||||
searchResult: [
|
||||
{ name: 'name1', address: 'address1' },
|
||||
{ name: 'name2' },
|
||||
{ address: 'address2' }
|
||||
]
|
||||
}
|
||||
{ address: 'address2' },
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const field = wrapper.findAll('.van-field__control').at(3);
|
||||
@@ -266,8 +266,8 @@ test('delete address', async () => {
|
||||
const wrapper = mount(AddressEdit, {
|
||||
attachToDocument: true,
|
||||
propsData: {
|
||||
showDelete: true
|
||||
}
|
||||
showDelete: true,
|
||||
},
|
||||
});
|
||||
|
||||
const deleteButton = wrapper.findAll('.van-button').at(1);
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
// Utils
|
||||
import { createNamespace } from '../utils';
|
||||
import { emit, inherit } from '../utils/functional';
|
||||
|
||||
// Components
|
||||
import Tag from '../tag';
|
||||
import Icon from '../icon';
|
||||
import Cell from '../cell';
|
||||
import Radio from '../radio';
|
||||
import Tag from '../tag';
|
||||
|
||||
// Types
|
||||
import { CreateElement, RenderContext } from 'vue/types';
|
||||
@@ -77,7 +80,7 @@ function AddressItem(
|
||||
{`${data.name} ${data.tel}`}
|
||||
{genTag()}
|
||||
</div>,
|
||||
<div class={bem('address')}>{data.address}</div>
|
||||
<div class={bem('address')}>{data.address}</div>,
|
||||
];
|
||||
|
||||
if (switchable && !disabled) {
|
||||
@@ -99,7 +102,7 @@ function AddressItem(
|
||||
clickable={switchable && !disabled}
|
||||
scopedSlots={{
|
||||
default: genContent,
|
||||
'right-icon': genRightIcon
|
||||
'right-icon': genRightIcon,
|
||||
}}
|
||||
onClick={onClick}
|
||||
{...inherit(ctx)}
|
||||
@@ -111,7 +114,7 @@ AddressItem.props = {
|
||||
data: Object,
|
||||
disabled: Boolean,
|
||||
switchable: Boolean,
|
||||
defaultTagText: String
|
||||
defaultTagText: String,
|
||||
};
|
||||
|
||||
export default createComponent<AddressItemProps, AddressItemEvents>(
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
### Install
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
import Vue from 'vue';
|
||||
import { AddressList } from 'vant';
|
||||
|
||||
@@ -25,7 +25,9 @@ Vue.use(AddressList);
|
||||
/>
|
||||
```
|
||||
|
||||
```javascript
|
||||
```js
|
||||
import { Toast } from 'vant';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
@@ -54,7 +56,6 @@ export default {
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
onAdd() {
|
||||
Toast('Add');
|
||||
@@ -95,9 +96,9 @@ export default {
|
||||
|
||||
| Key | Description | Type |
|
||||
|------|------|------|
|
||||
| id | Id | *string \| number* |
|
||||
| id | Id | *number \| string* |
|
||||
| name | Name | *string* |
|
||||
| tel | Phone | *string \| number* |
|
||||
| tel | Phone | *number \| string* |
|
||||
| address | Address | *string* |
|
||||
| isDefault | Is default address | *boolean* |
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
### 引入
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
import Vue from 'vue';
|
||||
import { AddressList } from 'vant';
|
||||
|
||||
@@ -25,7 +25,9 @@ Vue.use(AddressList);
|
||||
/>
|
||||
```
|
||||
|
||||
```javascript
|
||||
```js
|
||||
import { Toast } from 'vant';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
@@ -54,12 +56,10 @@ export default {
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
onAdd() {
|
||||
Toast('新增地址');
|
||||
},
|
||||
|
||||
onEdit(item, index) {
|
||||
Toast('编辑地址:' + index);
|
||||
}
|
||||
@@ -96,9 +96,9 @@ export default {
|
||||
|
||||
| 键名 | 说明 | 类型 |
|
||||
|------|------|------|
|
||||
| id | 每条地址的唯一标识 | *string \| number* |
|
||||
| id | 每条地址的唯一标识 | *number \| string* |
|
||||
| name | 收货人姓名 | *string* |
|
||||
| tel | 收货人手机号 | *string \| number* |
|
||||
| tel | 收货人手机号 | *number \| string* |
|
||||
| address | 收货地址 | *string* |
|
||||
| isDefault | 是否为默认地址 | *boolean* |
|
||||
|
||||
|
||||
@@ -24,27 +24,27 @@ export default {
|
||||
name: '张三',
|
||||
tel: '13000000000',
|
||||
address: '浙江省杭州市西湖区文三路 138 号东方通信大厦 7 楼 501 室',
|
||||
isDefault: true
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
name: '李四',
|
||||
tel: '1310000000',
|
||||
address: '浙江省杭州市拱墅区莫干山路 50 号'
|
||||
}
|
||||
address: '浙江省杭州市拱墅区莫干山路 50 号',
|
||||
},
|
||||
],
|
||||
disabledList: [
|
||||
{
|
||||
id: '3',
|
||||
name: '王五',
|
||||
tel: '1320000000',
|
||||
address: '浙江省杭州市滨江区江南大道 15 号'
|
||||
}
|
||||
address: '浙江省杭州市滨江区江南大道 15 号',
|
||||
},
|
||||
],
|
||||
add: '新增地址',
|
||||
edit: '编辑地址',
|
||||
disabledText: '以下地址超出配送范围',
|
||||
defaultTagText: '默认'
|
||||
defaultTagText: '默认',
|
||||
},
|
||||
'en-US': {
|
||||
list: [
|
||||
@@ -53,33 +53,33 @@ export default {
|
||||
name: 'John Snow',
|
||||
tel: '13000000000',
|
||||
address: 'Somewhere',
|
||||
isDefault: true
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
name: 'Ned Stark',
|
||||
tel: '1310000000',
|
||||
address: 'Somewhere'
|
||||
}
|
||||
address: 'Somewhere',
|
||||
},
|
||||
],
|
||||
disabledList: [
|
||||
{
|
||||
id: '3',
|
||||
name: 'Tywin',
|
||||
tel: '1320000000',
|
||||
address: 'Somewhere'
|
||||
}
|
||||
address: 'Somewhere',
|
||||
},
|
||||
],
|
||||
add: 'Add',
|
||||
edit: 'Edit',
|
||||
disabledText: 'The following address is out of range',
|
||||
defaultTagText: 'Default'
|
||||
}
|
||||
defaultTagText: 'Default',
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
chosenAddressId: '1'
|
||||
chosenAddressId: '1',
|
||||
};
|
||||
},
|
||||
|
||||
@@ -90,8 +90,8 @@ export default {
|
||||
|
||||
onEdit(item, index) {
|
||||
this.$toast(`${this.$t('edit')}:${index}`);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
// Utils
|
||||
import { createNamespace } from '../utils';
|
||||
import { emit, inherit } from '../utils/functional';
|
||||
|
||||
// Components
|
||||
import Button from '../button';
|
||||
import RadioGroup from '../radio-group';
|
||||
import AddressItem, { AddressItemData } from './Item';
|
||||
@@ -66,7 +69,9 @@ function AddressList(
|
||||
<div class={bem()} {...inherit(ctx)}>
|
||||
{slots.top?.()}
|
||||
<RadioGroup value={props.value}>{List}</RadioGroup>
|
||||
{props.disabledText && <div class={bem('disabled-text')}>{props.disabledText}</div>}
|
||||
{props.disabledText && (
|
||||
<div class={bem('disabled-text')}>{props.disabledText}</div>
|
||||
)}
|
||||
{DisabledList}
|
||||
{slots.default?.()}
|
||||
<div class={bem('bottom')}>
|
||||
@@ -94,8 +99,8 @@ AddressList.props = {
|
||||
defaultTagText: String,
|
||||
switchable: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
default: true,
|
||||
},
|
||||
};
|
||||
|
||||
export default createComponent<AddressListProps>(AddressList);
|
||||
|
||||
@@ -6,22 +6,22 @@ const list = [
|
||||
id: '1',
|
||||
name: '张三',
|
||||
tel: '13000000000',
|
||||
address: '浙江省杭州市西湖区文三路 138 号东方通信大厦 7 楼 501 室'
|
||||
address: '浙江省杭州市西湖区文三路 138 号东方通信大厦 7 楼 501 室',
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
name: '李四',
|
||||
tel: '1310000000',
|
||||
address: '浙江省杭州市拱墅区莫干山路 50 号'
|
||||
}
|
||||
address: '浙江省杭州市拱墅区莫干山路 50 号',
|
||||
},
|
||||
];
|
||||
|
||||
test('unswitchable', () => {
|
||||
const wrapper = mount(AddressList, {
|
||||
propsData: {
|
||||
list,
|
||||
switchable: false
|
||||
}
|
||||
switchable: false,
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
@@ -31,13 +31,13 @@ test('select event', () => {
|
||||
const onSelect = jest.fn();
|
||||
const wrapper = mount(AddressList, {
|
||||
propsData: {
|
||||
list
|
||||
list,
|
||||
},
|
||||
context: {
|
||||
on: {
|
||||
select: onSelect
|
||||
}
|
||||
}
|
||||
select: onSelect,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
wrapper.find('.van-radio__icon').trigger('click');
|
||||
@@ -49,13 +49,13 @@ test('click-item event', () => {
|
||||
const onClickItem = jest.fn();
|
||||
const wrapper = mount(AddressList, {
|
||||
propsData: {
|
||||
list
|
||||
list,
|
||||
},
|
||||
context: {
|
||||
on: {
|
||||
'click-item': onClickItem
|
||||
}
|
||||
}
|
||||
'click-item': onClickItem,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
wrapper.find('.van-address-item').trigger('click');
|
||||
|
||||
+10
-10
@@ -6,7 +6,7 @@ The Picker component is usually used with [Popup](#/en-US/popup) Component.
|
||||
|
||||
### Install
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
import Vue from 'vue';
|
||||
import { Area } from 'vant';
|
||||
|
||||
@@ -60,16 +60,16 @@ Set `columns-num` with 2, you'll have a 2 level picker.
|
||||
|------|------|------|------|
|
||||
| value | the `code` of selected area | *string* | - |
|
||||
| title | Toolbar title | *string* | - |
|
||||
| area-list | Area data | *object* | - |
|
||||
| columns-num | level of picker | *string \| number* | `3` |
|
||||
| columns-placeholder `v2.2.5` | placeholder of columns | *string[]* | `[]` |
|
||||
| item-height | Option height | *number* | `44` |
|
||||
| loading | Whether to show loading prompt | *boolean* | `false` |
|
||||
| visible-item-count | Count of visible columns | *number* | `5` |
|
||||
| confirm-button-text | Text of confirm button | *string* | `Confirm` |
|
||||
| cancel-button-text | Text of cancel button | *string* | `Cancel` |
|
||||
| area-list | Area list data | *object* | - |
|
||||
| columns-placeholder `v2.2.5` | Placeholder of columns | *string[]* | `[]` |
|
||||
| loading | Whether to show loading prompt | *boolean* | `false` |
|
||||
| item-height | Option height | *number \| string* | `44` |
|
||||
| columns-num | Level of picker | *number \| string* | `3` |
|
||||
| visible-item-count | Count of visible columns | *number \| string* | `5` |
|
||||
| swipe-duration `v2.2.13` | Duration of the momentum animation,unit `ms` | *number \| string* | `1000` |
|
||||
| is-oversea-code `v2.1.4` | The method to validate oversea code | *() => boolean* | - |
|
||||
| swipe-duration `v2.2.13` | Duration of the momentum animation,unit `ms` | *number* | `1000` |
|
||||
|
||||
### Events
|
||||
|
||||
@@ -94,7 +94,7 @@ Each property is a simple key-value object, key is a 6-bit code of the area of w
|
||||
|
||||
Example of `AreaList`
|
||||
|
||||
```javascript
|
||||
```js
|
||||
{
|
||||
province_list: {
|
||||
110000: 'Beijing',
|
||||
@@ -123,7 +123,7 @@ All code of China: [Area.json](https://github.com/youzan/vant/blob/dev/src/area/
|
||||
An array contains selected area objects.
|
||||
|
||||
`code` - code of selected area, `name` - name of selected area
|
||||
```javascript
|
||||
```js
|
||||
[{
|
||||
code: '330000',
|
||||
name: 'Zhejiang Province'
|
||||
|
||||
+12
-12
@@ -2,11 +2,11 @@
|
||||
|
||||
### 介绍
|
||||
|
||||
省市区选择组件通常与 [弹出层](#/zh-CN/popup) 组件配合使用
|
||||
省市区三级联动选择,通常与 [弹出层](#/zh-CN/popup) 组件配合使用
|
||||
|
||||
### 引入
|
||||
|
||||
```javascript
|
||||
```js
|
||||
import Vue from 'vue';
|
||||
import { Area } from 'vant';
|
||||
|
||||
@@ -59,16 +59,16 @@ Vue.use(Area);
|
||||
|------|------|------|------|
|
||||
| value | 当前选中的省市区`code` | *string* | - |
|
||||
| title | 顶部栏标题 | *string* | - |
|
||||
| area-list | 省市区数据,格式见下方 | *object* | - |
|
||||
| columns-num | 显示列数,3-省市区,2-省市,1-省 | *string \| number* | `3` |
|
||||
| columns-placeholder `v2.2.5` | 列占位提示文字 | *string[]* | `[]` |
|
||||
| loading | 是否显示加载状态 | *boolean* | `false` |
|
||||
| item-height | 选项高度 | *number* | `44` |
|
||||
| visible-item-count | 可见的选项个数 | *number* | `5` |
|
||||
| confirm-button-text | 确认按钮文字 | *string* | `确认` |
|
||||
| cancel-button-text | 取消按钮文字 | *string* | `取消` |
|
||||
| area-list | 省市区数据,格式见下方 | *object* | - |
|
||||
| columns-placeholder `v2.2.5` | 列占位提示文字 | *string[]* | `[]` |
|
||||
| loading | 是否显示加载状态 | *boolean* | `false` |
|
||||
| item-height | 选项高度 | *number \| string* | `44` |
|
||||
| columns-num | 显示列数,3-省市区,2-省市,1-省 | *number \| string* | `3` |
|
||||
| visible-item-count | 可见的选项个数 | *number \| string* | `5` |
|
||||
| swipe-duration `v2.2.13` | 快速滑动时惯性滚动的时长,单位`ms` | *number \| string* | `1000` |
|
||||
| is-oversea-code `v2.1.4` | 根据`code`校验海外地址,海外地址会划分至单独的分类 | *() => boolean* | - |
|
||||
| swipe-duration `v2.2.13` | 快速滑动时惯性滚动的时长,单位`ms` | *number* | `1000` |
|
||||
|
||||
### Events
|
||||
|
||||
@@ -80,7 +80,7 @@ Vue.use(Area);
|
||||
|
||||
### 方法
|
||||
|
||||
通过 [ref](https://cn.vuejs.org/v2/api/#ref) 可以获取到 Area 实例并调用实例方法
|
||||
通过 ref 可以获取到 Area 实例并调用实例方法,详见 [组件实例方法](#/zh-CN/quickstart#zu-jian-shi-li-fang-fa)
|
||||
|
||||
| 方法名 | 说明 | 参数 | 返回值 |
|
||||
|------|------|------|------|
|
||||
@@ -94,7 +94,7 @@ Vue.use(Area);
|
||||
|
||||
`AreaList`具体格式如下:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
{
|
||||
province_list: {
|
||||
110000: '北京市',
|
||||
@@ -129,7 +129,7 @@ Vue.use(Area);
|
||||
|
||||
`code` 代表被选中的地区编码, `name` 代表被选中的地区名称
|
||||
|
||||
```javascript
|
||||
```js
|
||||
[
|
||||
{
|
||||
code: '110000',
|
||||
|
||||
@@ -2,7 +2,7 @@ export default {
|
||||
province_list: {
|
||||
110000: 'Beijing',
|
||||
330000: 'Zhejiang',
|
||||
810000: 'Hong Kong'
|
||||
810000: 'Hong Kong',
|
||||
},
|
||||
city_list: {
|
||||
110100: 'Beijing City',
|
||||
@@ -13,7 +13,7 @@ export default {
|
||||
331100: 'Lishui',
|
||||
810100: 'Hong Kong Island',
|
||||
810200: 'Kowloon',
|
||||
810300: 'New Territories'
|
||||
810300: 'New Territories',
|
||||
},
|
||||
county_list: {
|
||||
110101: 'Dongcheng',
|
||||
@@ -66,6 +66,6 @@ export default {
|
||||
810305: 'Yuen Long',
|
||||
810306: 'Tuen Mun',
|
||||
810307: 'Tsuen Wan',
|
||||
810309: 'Lantau Island'
|
||||
}
|
||||
810309: 'Lantau Island',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -34,7 +34,7 @@ export default {
|
||||
710000: '台湾省',
|
||||
810000: '香港特别行政区',
|
||||
820000: '澳门特别行政区',
|
||||
900000: '海外'
|
||||
900000: '海外',
|
||||
},
|
||||
city_list: {
|
||||
110100: '北京市',
|
||||
@@ -648,7 +648,7 @@ export default {
|
||||
987600: '瓦利斯和富图纳',
|
||||
988200: '萨摩亚',
|
||||
988700: '也门',
|
||||
989400: '赞比亚'
|
||||
989400: '赞比亚',
|
||||
},
|
||||
county_list: {
|
||||
110101: '东城区',
|
||||
@@ -4035,6 +4035,6 @@ export default {
|
||||
810308: '葵青区',
|
||||
810309: '离岛区',
|
||||
820101: '澳门半岛',
|
||||
820201: '离岛'
|
||||
}
|
||||
820201: '离岛',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
export default {
|
||||
province_list: {
|
||||
110000: '北京市',
|
||||
120000: '天津市'
|
||||
120000: '天津市',
|
||||
},
|
||||
city_list: {
|
||||
110100: '北京市',
|
||||
110200: '县',
|
||||
120100: '天津市',
|
||||
120200: '县'
|
||||
120200: '县',
|
||||
},
|
||||
county_list: {
|
||||
110101: '东城区',
|
||||
@@ -16,6 +16,6 @@ export default {
|
||||
110229: '延庆县',
|
||||
120101: '和平区',
|
||||
120102: '河东区',
|
||||
120225: '蓟县'
|
||||
}
|
||||
120225: '蓟县',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -5,10 +5,7 @@
|
||||
</demo-block>
|
||||
|
||||
<demo-block :title="$t('title2')">
|
||||
<van-area
|
||||
:area-list="$t('areaList')"
|
||||
:value="value"
|
||||
/>
|
||||
<van-area :area-list="$t('areaList')" :value="value" />
|
||||
</demo-block>
|
||||
|
||||
<demo-block :title="$t('title3')">
|
||||
@@ -48,13 +45,13 @@ export default {
|
||||
title4: 'Columns Placeholder',
|
||||
columnsPlaceholder: ['Choose', 'Choose', 'Choose'],
|
||||
areaList: AreaListEn,
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
value: '330302'
|
||||
value: '330302',
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
+25
-25
@@ -16,26 +16,26 @@ export default createComponent({
|
||||
value: String,
|
||||
areaList: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
default: () => ({}),
|
||||
},
|
||||
columnsNum: {
|
||||
type: [Number, String],
|
||||
default: 3
|
||||
default: 3,
|
||||
},
|
||||
isOverseaCode: {
|
||||
type: Function,
|
||||
default: isOverseaCode
|
||||
default: isOverseaCode,
|
||||
},
|
||||
columnsPlaceholder: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
code: this.value,
|
||||
columns: [{ values: [] }, { values: [] }, { values: [] }]
|
||||
columns: [{ values: [] }, { values: [] }, { values: [] }],
|
||||
};
|
||||
},
|
||||
|
||||
@@ -60,27 +60,27 @@ export default createComponent({
|
||||
return {
|
||||
province: this.columnsPlaceholder[0] || '',
|
||||
city: this.columnsPlaceholder[1] || '',
|
||||
county: this.columnsPlaceholder[2] || ''
|
||||
county: this.columnsPlaceholder[2] || '',
|
||||
};
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
watch: {
|
||||
value() {
|
||||
this.code = this.value;
|
||||
value(val) {
|
||||
this.code = val;
|
||||
this.setValues();
|
||||
},
|
||||
|
||||
areaList: {
|
||||
deep: true,
|
||||
handler: 'setValues'
|
||||
handler: 'setValues',
|
||||
},
|
||||
|
||||
columnsNum() {
|
||||
this.$nextTick(() => {
|
||||
this.setValues();
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
@@ -98,7 +98,7 @@ export default createComponent({
|
||||
const list = this[type];
|
||||
result = Object.keys(list).map(listCode => ({
|
||||
code: listCode,
|
||||
name: list[listCode]
|
||||
name: list[listCode],
|
||||
}));
|
||||
|
||||
if (code) {
|
||||
@@ -112,16 +112,16 @@ export default createComponent({
|
||||
|
||||
if (this.placeholderMap[type] && result.length) {
|
||||
// set columns placeholder
|
||||
const codeFill =
|
||||
type === 'province'
|
||||
? ''
|
||||
: type === 'city'
|
||||
? PLACEHOLDER_CODE.slice(2, 4)
|
||||
: PLACEHOLDER_CODE.slice(4, 6);
|
||||
let codeFill = '';
|
||||
if (type === 'city') {
|
||||
codeFill = PLACEHOLDER_CODE.slice(2, 4);
|
||||
} else if (type === 'county') {
|
||||
codeFill = PLACEHOLDER_CODE.slice(4, 6);
|
||||
}
|
||||
|
||||
result.unshift({
|
||||
code: `${code}${codeFill}`,
|
||||
name: this.placeholderMap[type]
|
||||
name: this.placeholderMap[type],
|
||||
});
|
||||
}
|
||||
|
||||
@@ -218,7 +218,7 @@ export default createComponent({
|
||||
picker.setIndexes([
|
||||
this.getIndex('province', code),
|
||||
this.getIndex('city', code),
|
||||
this.getIndex('county', code)
|
||||
this.getIndex('county', code),
|
||||
]);
|
||||
},
|
||||
|
||||
@@ -236,7 +236,7 @@ export default createComponent({
|
||||
country: '',
|
||||
province: '',
|
||||
city: '',
|
||||
county: ''
|
||||
county: '',
|
||||
};
|
||||
|
||||
if (!values.length) {
|
||||
@@ -266,14 +266,14 @@ export default createComponent({
|
||||
reset(code) {
|
||||
this.code = code || '';
|
||||
this.setValues();
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
render() {
|
||||
const on = {
|
||||
...this.$listeners,
|
||||
change: this.onChange,
|
||||
confirm: this.onConfirm
|
||||
confirm: this.onConfirm,
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -293,5 +293,5 @@ export default createComponent({
|
||||
{...{ on }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
+26
-20
@@ -5,13 +5,13 @@ import { mount, later, triggerDrag } from '../../../test';
|
||||
const firstOption = [
|
||||
{ code: '110000', name: '北京市' },
|
||||
{ code: '110100', name: '北京市' },
|
||||
{ code: '110101', name: '东城区' }
|
||||
{ code: '110101', name: '东城区' },
|
||||
];
|
||||
|
||||
const secondOption = [
|
||||
{ code: '120000', name: '天津市' },
|
||||
{ code: '120100', name: '天津市' },
|
||||
{ code: '120101', name: '和平区' }
|
||||
{ code: '120101', name: '和平区' },
|
||||
];
|
||||
|
||||
test('confirm & cancel event', async () => {
|
||||
@@ -19,12 +19,12 @@ test('confirm & cancel event', async () => {
|
||||
const onCancel = jest.fn();
|
||||
const wrapper = mount(Area, {
|
||||
propsData: {
|
||||
areaList
|
||||
areaList,
|
||||
},
|
||||
listeners: {
|
||||
confirm: onConfirm,
|
||||
cancel: onCancel
|
||||
}
|
||||
cancel: onCancel,
|
||||
},
|
||||
});
|
||||
|
||||
await later();
|
||||
@@ -39,8 +39,8 @@ test('confirm & cancel event', async () => {
|
||||
test('watch areaList & code', async () => {
|
||||
const wrapper = mount(Area, {
|
||||
propsData: {
|
||||
areaList
|
||||
}
|
||||
areaList,
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
@@ -50,7 +50,7 @@ test('watch areaList & code', async () => {
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
|
||||
wrapper.setProps({
|
||||
value: ''
|
||||
value: '',
|
||||
});
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
@@ -59,22 +59,28 @@ test('change option', () => {
|
||||
const onChange = jest.fn();
|
||||
const wrapper = mount(Area, {
|
||||
propsData: {
|
||||
areaList
|
||||
areaList,
|
||||
},
|
||||
listeners: {
|
||||
change: onChange
|
||||
}
|
||||
change: onChange,
|
||||
},
|
||||
});
|
||||
|
||||
const columns = wrapper.findAll('.van-picker-column');
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
|
||||
triggerDrag(columns.at(0), 0, -100);
|
||||
columns.at(0).find('ul').trigger('transitionend');
|
||||
columns
|
||||
.at(0)
|
||||
.find('ul')
|
||||
.trigger('transitionend');
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
|
||||
triggerDrag(columns.at(2), 0, -100);
|
||||
columns.at(2).find('ul').trigger('transitionend');
|
||||
columns
|
||||
.at(2)
|
||||
.find('ul')
|
||||
.trigger('transitionend');
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
|
||||
expect(onChange.mock.calls[0][1]).toEqual(secondOption);
|
||||
@@ -83,11 +89,11 @@ test('change option', () => {
|
||||
test('getValues method', () => {
|
||||
const wrapper = mount(Area, {
|
||||
propsData: {
|
||||
areaList
|
||||
areaList,
|
||||
},
|
||||
created() {
|
||||
expect(this.getValues()).toEqual([]);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper.vm.getValues()).toEqual(firstOption);
|
||||
@@ -97,8 +103,8 @@ test('reset method', async () => {
|
||||
const wrapper = mount(Area, {
|
||||
propsData: {
|
||||
areaList,
|
||||
value: '120225'
|
||||
}
|
||||
value: '120225',
|
||||
},
|
||||
});
|
||||
|
||||
await later();
|
||||
@@ -111,12 +117,12 @@ test('columns-num prop', async () => {
|
||||
const wrapper = mount(Area, {
|
||||
propsData: {
|
||||
areaList,
|
||||
columnsNum: 3
|
||||
}
|
||||
columnsNum: 3,
|
||||
},
|
||||
});
|
||||
|
||||
wrapper.setProps({
|
||||
columnsNum: 2
|
||||
columnsNum: 2,
|
||||
});
|
||||
|
||||
await later();
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
### Install
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
import Vue from 'vue';
|
||||
import { Button } from 'vant';
|
||||
|
||||
@@ -74,6 +74,12 @@ Vue.use(Button);
|
||||
<van-button type="primary" size="mini">Mini</van-button>
|
||||
```
|
||||
|
||||
### Block Element
|
||||
|
||||
```html
|
||||
<van-button type="primary" block>Block Element</van-button>
|
||||
```
|
||||
|
||||
### Route
|
||||
|
||||
```html
|
||||
@@ -89,11 +95,6 @@ Vue.use(Button);
|
||||
<van-button color="linear-gradient(to right, #4bb0ff, #6149f6)">Gradient</van-button>
|
||||
```
|
||||
|
||||
### Block Element
|
||||
```html
|
||||
<van-button type="primary" block>Block Element</van-button>
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### Props
|
||||
|
||||
+11
-12
@@ -2,7 +2,7 @@
|
||||
|
||||
### 引入
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
import Vue from 'vue';
|
||||
import { Button } from 'vant';
|
||||
|
||||
@@ -90,6 +90,14 @@ Vue.use(Button);
|
||||
<van-button type="primary" size="mini">迷你按钮</van-button>
|
||||
```
|
||||
|
||||
### 块级元素
|
||||
|
||||
按钮在默认情况下为行内块级元素,通过`block`属性可以将按钮的元素类型设置为块级元素
|
||||
|
||||
```html
|
||||
<van-button type="primary" block>块级元素</van-button>
|
||||
```
|
||||
|
||||
### 页面导航
|
||||
|
||||
可以通过`url`属性进行 URL 跳转,或通过`to`属性进行路由跳转
|
||||
@@ -109,15 +117,6 @@ Vue.use(Button);
|
||||
<van-button color="linear-gradient(to right, #4bb0ff, #6149f6)">渐变色按钮</van-button>
|
||||
```
|
||||
|
||||
### 块级元素
|
||||
|
||||
通过`block`属性可以将按钮的元素类型设置为块级元素
|
||||
|
||||
```html
|
||||
<van-button type="primary" block>块级元素</van-button>
|
||||
```
|
||||
|
||||
|
||||
## API
|
||||
|
||||
### Props
|
||||
@@ -128,7 +127,7 @@ Vue.use(Button);
|
||||
| size | 尺寸,可选值为 `large` `small` `mini` | *string* | `normal` |
|
||||
| text | 按钮文字 | *string* | - |
|
||||
| color `v2.1.8` | 按钮颜色,支持传入`linear-gradient`渐变色 | *string* | - |
|
||||
| icon | 左侧图标名称或图片链接,可选值见 [Icon 组件](#/zh-CN/icon) | *string* | - |
|
||||
| icon | 左侧 [图标名称](#/zh-CN/icon) 或图片链接 | *string* | - |
|
||||
| tag | HTML 标签 | *string* | `button` |
|
||||
| native-type | 原生 button 标签 type 属性 | *string* | - |
|
||||
| block | 是否为块级元素 | *boolean* | `false` |
|
||||
@@ -139,7 +138,7 @@ Vue.use(Button);
|
||||
| hairline | 是否使用 0.5px 边框 | *boolean* | `false` |
|
||||
| loading | 是否显示为加载状态 | *boolean* | `false` |
|
||||
| loading-text | 加载状态提示文字 | *string* | - |
|
||||
| loading-type | 加载图标类型,可选值为`spinner` | *string* | `circular` |
|
||||
| loading-type | [加载图标类型](#/zh-CN/loading),可选值为`spinner` | *string* | `circular` |
|
||||
| loading-size | 加载图标大小 | *string* | `20px` |
|
||||
| url | 点击后跳转的链接地址 | *string* | - |
|
||||
| to | 点击后跳转的目标路由对象,同 vue-router 的 [to 属性](https://router.vuejs.org/zh/api/#to) | *string \| object* | - |
|
||||
|
||||
+17
-13
@@ -54,22 +54,26 @@
|
||||
<van-button type="primary" size="mini">{{ $t('mini') }}</van-button>
|
||||
</demo-block>
|
||||
|
||||
<demo-block :title="$t('blockElement')">
|
||||
<van-button type="primary" block>{{ $t('blockElement') }}</van-button>
|
||||
</demo-block>
|
||||
|
||||
<demo-block :title="$t('router')">
|
||||
<van-button :text="$t('urlRoute')" type="primary" url="/vant/mobile.html" />
|
||||
<van-button
|
||||
:text="$t('urlRoute')"
|
||||
type="primary"
|
||||
url="/vant/mobile.html"
|
||||
/>
|
||||
<van-button :text="$t('vueRoute')" type="primary" to="index" />
|
||||
</demo-block>
|
||||
|
||||
<demo-block :title="$t('customColor')">
|
||||
<van-button color="#7232dd" :text="$t('pure')" />
|
||||
<van-button plain color="#7232dd" :text="$t('pure')" />
|
||||
<van-button color="linear-gradient(to right, #4bb0ff, #6149f6)" :text="$t('gradient')" />
|
||||
</demo-block>
|
||||
|
||||
<demo-block :title="$t('blockElement')">
|
||||
<div class="demo-button-row">
|
||||
<van-button type="primary">{{ $t('normal') }}</van-button>
|
||||
</div>
|
||||
<van-button type="primary" block>{{ $t('blockElement') }}</van-button>
|
||||
<van-button
|
||||
color="linear-gradient(to right, #4bb0ff, #6149f6)"
|
||||
:text="$t('gradient')"
|
||||
/>
|
||||
</demo-block>
|
||||
</demo-section>
|
||||
</template>
|
||||
@@ -104,7 +108,7 @@ export default {
|
||||
customColor: '自定义颜色',
|
||||
pure: '单色按钮',
|
||||
gradient: '渐变色按钮',
|
||||
blockElement: '块级元素'
|
||||
blockElement: '块级元素',
|
||||
},
|
||||
'en-US': {
|
||||
type: 'Type',
|
||||
@@ -133,9 +137,9 @@ export default {
|
||||
customColor: 'Custom Color',
|
||||
pure: 'Pure',
|
||||
gradient: 'Gradient',
|
||||
blockElement: 'Block Element'
|
||||
}
|
||||
}
|
||||
blockElement: 'Block Element',
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
}
|
||||
|
||||
&:active::before {
|
||||
opacity: .1;
|
||||
opacity: 0.1;
|
||||
}
|
||||
|
||||
&--loading,
|
||||
|
||||
+12
-9
@@ -1,7 +1,10 @@
|
||||
// Utils
|
||||
import { createNamespace } from '../utils';
|
||||
import { emit, inherit } from '../utils/functional';
|
||||
import { BORDER_SURROUND, WHITE } from '../utils/constant';
|
||||
import { routeProps, RouteProps, functionalRoute } from '../utils/router';
|
||||
|
||||
// Components
|
||||
import Icon from '../icon';
|
||||
import Loading, { LoadingType } from '../loading';
|
||||
|
||||
@@ -54,7 +57,7 @@ function Button(
|
||||
disabled,
|
||||
loading,
|
||||
hairline,
|
||||
loadingText
|
||||
loadingText,
|
||||
} = props;
|
||||
|
||||
const style: Record<string, string | number> = {};
|
||||
@@ -97,10 +100,10 @@ function Button(
|
||||
hairline,
|
||||
block: props.block,
|
||||
round: props.round,
|
||||
square: props.square
|
||||
}
|
||||
square: props.square,
|
||||
},
|
||||
]),
|
||||
{ [BORDER_SURROUND]: hairline }
|
||||
{ [BORDER_SURROUND]: hairline },
|
||||
];
|
||||
|
||||
function Content() {
|
||||
@@ -165,20 +168,20 @@ Button.props = {
|
||||
loadingType: String,
|
||||
tag: {
|
||||
type: String,
|
||||
default: 'button'
|
||||
default: 'button',
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'default'
|
||||
default: 'default',
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
default: 'normal'
|
||||
default: 'normal',
|
||||
},
|
||||
loadingSize: {
|
||||
type: String,
|
||||
default: '20px'
|
||||
}
|
||||
default: '20px',
|
||||
},
|
||||
};
|
||||
|
||||
export default createComponent<ButtonProps, ButtonEvents>(Button);
|
||||
|
||||
@@ -21,10 +21,8 @@ exports[`renders demo correctly 1`] = `
|
||||
<!----></i><span class="van-button__text">按钮</span></button> <button class="van-button van-button--primary van-button--normal van-button--plain"><i class="van-icon van-button__icon"><img src="https://img.yzcdn.cn/vant/logo.png" class="van-icon__image">
|
||||
<!----></i><span class="van-button__text">按钮</span></button></div>
|
||||
<div><button class="van-button van-button--primary van-button--large"><span class="van-button__text">大号按钮</span></button> <button class="van-button van-button--primary van-button--normal"><span class="van-button__text">普通按钮</span></button> <button class="van-button van-button--primary van-button--small"><span class="van-button__text">小型按钮</span></button> <button class="van-button van-button--primary van-button--mini"><span class="van-button__text">迷你按钮</span></button></div>
|
||||
<div><button class="van-button van-button--primary van-button--normal van-button--block"><span class="van-button__text">块级元素</span></button></div>
|
||||
<div><button class="van-button van-button--primary van-button--normal"><span class="van-button__text">URL 跳转</span></button> <button class="van-button van-button--primary van-button--normal"><span class="van-button__text">路由跳转</span></button></div>
|
||||
<div><button class="van-button van-button--default van-button--normal" style="color: rgb(255, 255, 255); background: rgb(114, 50, 221); border-color: #7232dd;"><span class="van-button__text">单色按钮</span></button> <button class="van-button van-button--default van-button--normal van-button--plain" style="color: rgb(114, 50, 221); border-color: #7232dd;"><span class="van-button__text">单色按钮</span></button> <button class="van-button van-button--default van-button--normal" style="color: rgb(255, 255, 255); border: 0px;"><span class="van-button__text">渐变色按钮</span></button></div>
|
||||
<div>
|
||||
<div class="demo-button-row"><button class="van-button van-button--primary van-button--normal"><span class="van-button__text">普通按钮</span></button></div> <button class="van-button van-button--primary van-button--normal van-button--block"><span class="van-button__text">块级元素</span></button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -5,8 +5,8 @@ test('loading size', () => {
|
||||
const wrapper = mount(Button, {
|
||||
propsData: {
|
||||
loading: true,
|
||||
loadingSize: '10px'
|
||||
}
|
||||
loadingSize: '10px',
|
||||
},
|
||||
});
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
@@ -16,9 +16,9 @@ test('click event', () => {
|
||||
const wrapper = mount(Button, {
|
||||
context: {
|
||||
on: {
|
||||
click: onClick
|
||||
}
|
||||
}
|
||||
click: onClick,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
wrapper.trigger('click');
|
||||
@@ -29,13 +29,13 @@ test('not trigger click event when disabled', () => {
|
||||
const onClick = jest.fn();
|
||||
const wrapper = mount(Button, {
|
||||
propsData: {
|
||||
disabled: true
|
||||
disabled: true,
|
||||
},
|
||||
context: {
|
||||
on: {
|
||||
click: onClick
|
||||
}
|
||||
}
|
||||
click: onClick,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
wrapper.trigger('click');
|
||||
@@ -46,13 +46,13 @@ test('not trigger click event when loading', () => {
|
||||
const onClick = jest.fn();
|
||||
const wrapper = mount(Button, {
|
||||
propsData: {
|
||||
loading: true
|
||||
loading: true,
|
||||
},
|
||||
context: {
|
||||
on: {
|
||||
click: onClick
|
||||
}
|
||||
}
|
||||
click: onClick,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
wrapper.trigger('click');
|
||||
@@ -64,9 +64,9 @@ test('touchstart event', () => {
|
||||
const wrapper = mount(Button, {
|
||||
context: {
|
||||
on: {
|
||||
touchstart: onTouchstart
|
||||
}
|
||||
}
|
||||
touchstart: onTouchstart,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
wrapper.trigger('touchstart');
|
||||
@@ -76,8 +76,8 @@ test('touchstart event', () => {
|
||||
test('hide border when color is gradient', () => {
|
||||
const wrapper = mount(Button, {
|
||||
propsData: {
|
||||
color: 'linear-gradient(#000, #fff)'
|
||||
}
|
||||
color: 'linear-gradient(#000, #fff)',
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper.element.style.border).toEqual('0px');
|
||||
|
||||
+18
-6
@@ -6,7 +6,7 @@ Calendar component for selecting dates or date ranges
|
||||
|
||||
### Install
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
import Vue from 'vue';
|
||||
import { Calendar } from 'vant';
|
||||
|
||||
@@ -21,7 +21,6 @@ The `confirm` event will be triggered after the date selection is completed
|
||||
|
||||
```html
|
||||
<van-cell title="Select Single Date" :value="date" @click="show = true" />
|
||||
|
||||
<van-calendar v-model="show" @confirm="onConfirm" />
|
||||
```
|
||||
|
||||
@@ -33,7 +32,6 @@ export default {
|
||||
show: false
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
formatDate(date) {
|
||||
return `${date.getMonth() + 1}/${date.getDate()}`;
|
||||
@@ -52,7 +50,6 @@ You can select a date range after setting `type` to` range`. In range mode, the
|
||||
|
||||
```html
|
||||
<van-cell title="Select Date Range" :value="date" @click="show = true" />
|
||||
|
||||
<van-calendar v-model="show" type="range" @confirm="onConfirm" />
|
||||
```
|
||||
|
||||
@@ -64,7 +61,6 @@ export default {
|
||||
show: false
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
formatDate(date) {
|
||||
return `${date.getMonth() + 1}/${date.getDate()}`;
|
||||
@@ -184,6 +180,18 @@ Use `position` to custom popup position,can be set to `top`、`left`、`right`
|
||||
/>
|
||||
```
|
||||
|
||||
### Max Range
|
||||
|
||||
When selecting a date range, you can use the `max-range` prop to specify the maximum number of selectable days
|
||||
|
||||
```html
|
||||
<van-calendar
|
||||
type="range"
|
||||
:max-range="3"
|
||||
:style="{ height: '500px' }"
|
||||
/>
|
||||
```
|
||||
|
||||
### Tiled display
|
||||
|
||||
Set `poppable` to `false`, the calendar will be displayed directly on the page instead of appearing as a popup
|
||||
@@ -210,17 +218,21 @@ Set `poppable` to `false`, the calendar will be displayed directly on the page i
|
||||
| min-date | Min date | *Date* | Today |
|
||||
| max-date | Max date | *Date* | Six months after the today |
|
||||
| default-date | Default selected date | *Date \| Date[]* | Today |
|
||||
| row-height | Row height | *number* | `64` |
|
||||
| row-height | Row height | *number \| string* | `64` |
|
||||
| formatter | Day formatter | *(day: Day) => Day* | - |
|
||||
| position | Popup position, can be set to `top` `right` `left` | *string* | `bottom` |
|
||||
| poppable | Whether to show the calendar inside a popup | *boolean* | `true` |
|
||||
| round | Whether to show round corner | *boolean* | `true` |
|
||||
| show-mark | Whether to show background month mark | *boolean* | `true` |
|
||||
| show-confirm | Whether to show confirm button | *boolean* | `true` |
|
||||
| close-on-popstate `v2.4.4` | Whether to close when popstate | *boolean* | `false` |
|
||||
| close-on-click-overlay | Whether to close when click overlay | *boolean* | `true` |
|
||||
| safe-area-inset-bottom | Whether to enable bottom safe area adaptation | *boolean* | `true` |
|
||||
| confirm-text | Confirm button text | *string* | `Confirm` |
|
||||
| confirm-disabled-text | Confirm button text when disabled | *string* | `Confirm` |
|
||||
| max-range `v2.4.3` | Number of selectable days | *number \| string* | - |
|
||||
| range-prompt `v2.4.3` | Error message when exceeded max range | *string* | `Choose no more than xx days` |
|
||||
| get-container `v2.4.4` | Return the mount node for Calendar | _string \| () => Element_ | - |
|
||||
|
||||
### Data Structure of Day
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
### 引入
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
import Vue from 'vue';
|
||||
import { Calendar } from 'vant';
|
||||
|
||||
@@ -21,7 +21,6 @@ Vue.use(Calendar);
|
||||
|
||||
```html
|
||||
<van-cell title="选择单个日期" :value="date" @click="show = true" />
|
||||
|
||||
<van-calendar v-model="show" @confirm="onConfirm" />
|
||||
```
|
||||
|
||||
@@ -33,7 +32,6 @@ export default {
|
||||
show: false
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
formatDate(date) {
|
||||
return `${date.getMonth() + 1}/${date.getDate()}`;
|
||||
@@ -52,7 +50,6 @@ export default {
|
||||
|
||||
```html
|
||||
<van-cell title="选择日期区间" :value="date" @click="show = true" />
|
||||
|
||||
<van-calendar v-model="show" type="range" @confirm="onConfirm" />
|
||||
```
|
||||
|
||||
@@ -64,7 +61,6 @@ export default {
|
||||
show: false
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
formatDate(date) {
|
||||
return `${date.getMonth() + 1}/${date.getDate()}`;
|
||||
@@ -184,6 +180,18 @@ export default {
|
||||
/>
|
||||
```
|
||||
|
||||
### 日期区间最大范围
|
||||
|
||||
选择日期区间时,可以通过`max-range`属性来指定最多可选天数,选择的范围超过最多可选天数时,会弹出相应的提示文案
|
||||
|
||||
```html
|
||||
<van-calendar
|
||||
type="range"
|
||||
:max-range="3"
|
||||
:style="{ height: '500px' }"
|
||||
/>
|
||||
```
|
||||
|
||||
### 平铺展示
|
||||
|
||||
将`poppable`设置为`false`,日历会直接展示在页面内,而不是以弹层的形式出现
|
||||
@@ -210,17 +218,21 @@ export default {
|
||||
| min-date | 最小日期 | *Date* | 当前日期 |
|
||||
| max-date | 最大日期 | *Date* | 当前日期的六个月后 |
|
||||
| default-date | 默认选中的日期 | *Date \| Date[]* | 今天 |
|
||||
| row-height | 日期行高 | *number* | `64` |
|
||||
| row-height | 日期行高 | *number \| string* | `64` |
|
||||
| formatter | 日期格式化函数 | *(day: Day) => Day* | - |
|
||||
| position | 弹出位置,可选值为 `top` `right` `left` | *string* | `bottom` |
|
||||
| poppable | 是否以弹层的形式展示日历 | *boolean* | `true` |
|
||||
| round | 是否显示圆角弹窗 | *boolean* | `true` |
|
||||
| show-mark | 是否显示月份背景水印 | *boolean* | `true` |
|
||||
| show-confirm | 是否展示确认按钮 | *boolean* | `true` |
|
||||
| close-on-popstate `v2.4.4` | 是否在页面回退时自动关闭 | *boolean* | `false` |
|
||||
| close-on-click-overlay | 是否在点击遮罩层后关闭 | *boolean* | `true` |
|
||||
| safe-area-inset-bottom | 是否开启底部安全区适配,[详细说明](#/zh-CN/quickstart#di-bu-an-quan-qu-gua-pei) | *boolean* | `true` |
|
||||
| safe-area-inset-bottom | 是否开启 [底部安全区适配](#/zh-CN/quickstart#di-bu-an-quan-qu-gua-pei) | *boolean* | `true` |
|
||||
| confirm-text | 确认按钮的文字 | *string* | `确定` |
|
||||
| confirm-disabled-text | 确认按钮处于禁用状态时的文字 | *string* | `确定` |
|
||||
| max-range `v2.4.3` | 日期区间最多可选天数,默认无限制 | *number \| string* | - |
|
||||
| range-prompt `v2.4.3` | 选择超过区间范围时的提示文案 | *string* | `选择天数不能超过 xx 天` |
|
||||
| get-container `v2.4.4` | 指定挂载的节点,[用法示例](#/zh-CN/popup#zhi-ding-gua-zai-wei-zhi) | *string \| () => Element* | - |
|
||||
|
||||
### Day 数据结构
|
||||
|
||||
@@ -251,7 +263,7 @@ export default {
|
||||
|
||||
### 方法
|
||||
|
||||
通过 [ref](https://cn.vuejs.org/v2/api/#ref) 可以获取到 Calendar 实例并调用实例方法
|
||||
通过 ref 可以获取到 Calendar 实例并调用实例方法,详见 [组件实例方法](#/zh-CN/quickstart#zu-jian-shi-li-fang-fa)
|
||||
|
||||
| 方法名 | 说明 | 参数 | 返回值 |
|
||||
|------|------|------|------|
|
||||
|
||||
@@ -6,7 +6,7 @@ const [createComponent] = createNamespace('calendar-header');
|
||||
export default createComponent({
|
||||
props: {
|
||||
title: String,
|
||||
monthTitle: String
|
||||
monthTitle: String,
|
||||
},
|
||||
|
||||
methods: {
|
||||
@@ -29,7 +29,7 @@ export default createComponent({
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
render() {
|
||||
@@ -40,5 +40,5 @@ export default createComponent({
|
||||
{this.genWeekDays()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -13,14 +13,14 @@ export default createComponent({
|
||||
maxDate: Date,
|
||||
showMark: Boolean,
|
||||
showTitle: Boolean,
|
||||
rowHeight: Number,
|
||||
rowHeight: [Number, String],
|
||||
formatter: Function,
|
||||
currentDate: [Date, Array]
|
||||
currentDate: [Date, Array],
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
visible: false
|
||||
visible: false,
|
||||
};
|
||||
},
|
||||
|
||||
@@ -43,7 +43,7 @@ export default createComponent({
|
||||
Math.ceil((this.totalDay + this.offset) / 7) * this.rowHeight;
|
||||
|
||||
return {
|
||||
paddingBottom: `${padding}px`
|
||||
paddingBottom: `${padding}px`,
|
||||
};
|
||||
}
|
||||
},
|
||||
@@ -61,7 +61,7 @@ export default createComponent({
|
||||
date,
|
||||
type,
|
||||
text: day,
|
||||
bottomInfo: this.getBottomInfo(type)
|
||||
bottomInfo: this.getBottomInfo(type),
|
||||
};
|
||||
|
||||
if (this.formatter) {
|
||||
@@ -72,7 +72,7 @@ export default createComponent({
|
||||
}
|
||||
|
||||
return days;
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
@@ -219,7 +219,7 @@ export default createComponent({
|
||||
{BottomInfo}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
render() {
|
||||
@@ -229,5 +229,5 @@ export default createComponent({
|
||||
{this.genDays()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -67,6 +67,13 @@
|
||||
:value="formatFullDate(date.customPosition)"
|
||||
@click="show('single', 'customPosition')"
|
||||
/>
|
||||
|
||||
<van-cell
|
||||
is-link
|
||||
:title="$t('maxRange')"
|
||||
:value="formatRange(date.maxRange)"
|
||||
@click="show('range', 'maxRange')"
|
||||
/>
|
||||
</demo-block>
|
||||
|
||||
<demo-block :title="$t('tiledDisplay')">
|
||||
@@ -85,9 +92,10 @@
|
||||
:type="type"
|
||||
:color="color"
|
||||
:round="round"
|
||||
:position="position"
|
||||
:min-date="minDate"
|
||||
:max-date="maxDate"
|
||||
:position="position"
|
||||
:max-range="maxRange"
|
||||
:formatter="formatter"
|
||||
:show-confirm="showConfirm"
|
||||
:confirm-text="confirmText"
|
||||
@@ -109,6 +117,7 @@ export default {
|
||||
laborDay: '劳动节',
|
||||
youthDay: '五四青年节',
|
||||
calendar: '日历',
|
||||
maxRange: '日期区间最大范围',
|
||||
selectSingle: '选择单个日期',
|
||||
selectRange: '选择日期区间',
|
||||
quickSelect: '快捷选择',
|
||||
@@ -120,7 +129,7 @@ export default {
|
||||
customPosition: '自定义弹出位置',
|
||||
customCalendar: '自定义日历',
|
||||
confirmDisabledText: '请选择结束时间',
|
||||
tiledDisplay: '平铺展示'
|
||||
tiledDisplay: '平铺展示',
|
||||
},
|
||||
'en-US': {
|
||||
in: 'In',
|
||||
@@ -129,6 +138,7 @@ export default {
|
||||
laborDay: 'Labor day',
|
||||
youthDay: 'Youth Day',
|
||||
calendar: 'Calendar',
|
||||
maxRange: 'Max Range',
|
||||
selectSingle: 'Select Single Date',
|
||||
selectRange: 'Select Date Range',
|
||||
quickSelect: 'Quick Select',
|
||||
@@ -140,13 +150,14 @@ export default {
|
||||
customPosition: 'Custom Position',
|
||||
customCalendar: 'Custom Calendar',
|
||||
confirmDisabledText: 'Select End Time',
|
||||
tiledDisplay: 'Tiled display'
|
||||
}
|
||||
tiledDisplay: 'Tiled display',
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
date: {
|
||||
maxRange: [],
|
||||
selectSingle: null,
|
||||
selectRange: [],
|
||||
quickSelect1: null,
|
||||
@@ -155,13 +166,14 @@ export default {
|
||||
customConfirm: [],
|
||||
customRange: null,
|
||||
customDayText: [],
|
||||
customPosition: null
|
||||
customPosition: null,
|
||||
},
|
||||
type: 'single',
|
||||
round: true,
|
||||
color: undefined,
|
||||
minDate: undefined,
|
||||
maxDate: undefined,
|
||||
maxRange: undefined,
|
||||
position: undefined,
|
||||
formatter: undefined,
|
||||
showConfirm: false,
|
||||
@@ -179,6 +191,7 @@ export default {
|
||||
this.color = undefined;
|
||||
this.minDate = undefined;
|
||||
this.maxDate = undefined;
|
||||
this.maxRange = undefined;
|
||||
this.position = undefined;
|
||||
this.formatter = undefined;
|
||||
this.showConfirm = true;
|
||||
@@ -217,6 +230,9 @@ export default {
|
||||
this.round = false;
|
||||
this.position = 'right';
|
||||
break;
|
||||
case 'maxRange':
|
||||
this.maxRange = 3;
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
@@ -265,7 +281,7 @@ export default {
|
||||
onConfirm(date) {
|
||||
this.showCalendar = false;
|
||||
this.date[this.id] = date;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
+72
-44
@@ -1,3 +1,4 @@
|
||||
// Utils
|
||||
import { isDate } from '../utils/validate/date';
|
||||
import { getScrollTop } from '../utils/dom/scroll';
|
||||
import {
|
||||
@@ -7,11 +8,14 @@ import {
|
||||
compareDay,
|
||||
compareMonth,
|
||||
createComponent,
|
||||
ROW_HEIGHT
|
||||
calcDateNum,
|
||||
ROW_HEIGHT,
|
||||
} from './utils';
|
||||
|
||||
// Components
|
||||
import Popup from '../popup';
|
||||
import Button from '../button';
|
||||
import Toast from '../toast';
|
||||
import Month from './components/Month';
|
||||
import Header from './components/Header';
|
||||
|
||||
@@ -21,17 +25,20 @@ export default createComponent({
|
||||
color: String,
|
||||
value: Boolean,
|
||||
formatter: Function,
|
||||
defaultDate: [Date, Array],
|
||||
confirmText: String,
|
||||
rangePrompt: String,
|
||||
defaultDate: [Date, Array],
|
||||
getContainer: [String, Function],
|
||||
closeOnPopstate: Boolean,
|
||||
confirmDisabledText: String,
|
||||
type: {
|
||||
type: String,
|
||||
default: 'single'
|
||||
default: 'single',
|
||||
},
|
||||
minDate: {
|
||||
type: Date,
|
||||
validator: isDate,
|
||||
default: () => new Date()
|
||||
default: () => new Date(),
|
||||
},
|
||||
maxDate: {
|
||||
type: Date,
|
||||
@@ -39,50 +46,58 @@ export default createComponent({
|
||||
default() {
|
||||
const now = new Date();
|
||||
return new Date(now.getFullYear(), now.getMonth() + 6, now.getDate());
|
||||
}
|
||||
},
|
||||
},
|
||||
position: {
|
||||
type: String,
|
||||
default: 'bottom'
|
||||
default: 'bottom',
|
||||
},
|
||||
rowHeight: {
|
||||
type: Number,
|
||||
default: ROW_HEIGHT
|
||||
type: [Number, String],
|
||||
default: ROW_HEIGHT,
|
||||
},
|
||||
round: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
default: true,
|
||||
},
|
||||
poppable: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
default: true,
|
||||
},
|
||||
showMark: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
default: true,
|
||||
},
|
||||
showConfirm: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
default: true,
|
||||
},
|
||||
safeAreaInsetBottom: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
default: true,
|
||||
},
|
||||
closeOnClickOverlay: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
default: true,
|
||||
},
|
||||
maxRange: {
|
||||
type: [Number, String],
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
monthTitle: '',
|
||||
currentDate: this.getInitialDate()
|
||||
currentDate: this.getInitialDate(),
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
range() {
|
||||
return this.type === 'range';
|
||||
},
|
||||
|
||||
months() {
|
||||
const months = [];
|
||||
const cursor = new Date(this.minDate);
|
||||
@@ -98,21 +113,16 @@ export default createComponent({
|
||||
},
|
||||
|
||||
buttonDisabled() {
|
||||
if (this.type === 'single') {
|
||||
return !this.currentDate;
|
||||
}
|
||||
|
||||
/* istanbul ignore else */
|
||||
if (this.type === 'range') {
|
||||
if (this.range) {
|
||||
return !this.currentDate[0] || !this.currentDate[1];
|
||||
}
|
||||
}
|
||||
|
||||
return !this.currentDate;
|
||||
},
|
||||
},
|
||||
|
||||
watch: {
|
||||
type() {
|
||||
this.reset();
|
||||
},
|
||||
type: 'reset',
|
||||
|
||||
value(val) {
|
||||
if (val) {
|
||||
@@ -123,7 +133,7 @@ export default createComponent({
|
||||
|
||||
defaultDate(val) {
|
||||
this.currentDate = val;
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
@@ -148,8 +158,8 @@ export default createComponent({
|
||||
// scroll to current month
|
||||
scrollIntoView() {
|
||||
this.$nextTick(() => {
|
||||
const { type, currentDate } = this;
|
||||
const targetDate = type === 'range' ? currentDate[0] : currentDate;
|
||||
const { currentDate } = this;
|
||||
const targetDate = this.range ? currentDate[0] : currentDate;
|
||||
|
||||
/* istanbul ignore if */
|
||||
if (!targetDate) {
|
||||
@@ -170,15 +180,12 @@ export default createComponent({
|
||||
getInitialDate() {
|
||||
const { type, defaultDate, minDate } = this;
|
||||
|
||||
if (type === 'single') {
|
||||
return defaultDate || minDate;
|
||||
}
|
||||
|
||||
/* istanbul ignore else */
|
||||
if (type === 'range') {
|
||||
const [startDay, endDay] = defaultDate || [];
|
||||
return [startDay || minDate, endDay || getNextDay(minDate)];
|
||||
}
|
||||
|
||||
return defaultDate || minDate;
|
||||
},
|
||||
|
||||
// calculate the position of the elements
|
||||
@@ -219,11 +226,7 @@ export default createComponent({
|
||||
onClickDay(item) {
|
||||
const { date } = item;
|
||||
|
||||
if (this.type === 'single') {
|
||||
this.select(date, true);
|
||||
}
|
||||
|
||||
if (this.type === 'range') {
|
||||
if (this.range) {
|
||||
const [startDay, endDay] = this.currentDate;
|
||||
|
||||
if (startDay && !endDay) {
|
||||
@@ -237,6 +240,8 @@ export default createComponent({
|
||||
} else {
|
||||
this.select([date, null]);
|
||||
}
|
||||
} else {
|
||||
this.select(date, true);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -248,13 +253,34 @@ export default createComponent({
|
||||
this.currentDate = date;
|
||||
this.$emit('select', this.currentDate);
|
||||
|
||||
if (complete && this.range) {
|
||||
const valid = this.checkRange();
|
||||
|
||||
if (!valid) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (complete && !this.showConfirm) {
|
||||
this.onConfirm();
|
||||
}
|
||||
},
|
||||
|
||||
checkRange() {
|
||||
const { maxRange, currentDate, rangePrompt } = this;
|
||||
|
||||
if (maxRange && calcDateNum(currentDate) > maxRange) {
|
||||
Toast(rangePrompt || t('rangePrompt', maxRange));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
onConfirm() {
|
||||
this.$emit('confirm', this.currentDate);
|
||||
if (this.checkRange()) {
|
||||
this.$emit('confirm', this.currentDate);
|
||||
}
|
||||
},
|
||||
|
||||
genMonth(date, index) {
|
||||
@@ -309,7 +335,7 @@ export default createComponent({
|
||||
return (
|
||||
<div
|
||||
class={bem('footer', {
|
||||
'safe-area-inset-bottom': this.safeAreaInsetBottom
|
||||
'safe-area-inset-bottom': this.safeAreaInsetBottom,
|
||||
})}
|
||||
>
|
||||
{this.genFooterContent()}
|
||||
@@ -324,7 +350,7 @@ export default createComponent({
|
||||
title={this.title}
|
||||
monthTitle={this.monthTitle}
|
||||
scopedSlots={{
|
||||
title: () => this.slots('title')
|
||||
title: () => this.slots('title'),
|
||||
}}
|
||||
/>
|
||||
<div ref="body" class={bem('body')} onScroll={this.onScroll}>
|
||||
@@ -333,7 +359,7 @@ export default createComponent({
|
||||
{this.genFooter()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
render() {
|
||||
@@ -346,6 +372,8 @@ export default createComponent({
|
||||
value={this.value}
|
||||
round={this.round}
|
||||
position={this.position}
|
||||
getContainer={this.getContainer}
|
||||
closeOnPopstate={this.closeOnPopstate}
|
||||
closeOnClickOverlay={this.closeOnClickOverlay}
|
||||
onInput={this.togglePopup}
|
||||
>
|
||||
@@ -355,5 +383,5 @@ export default createComponent({
|
||||
}
|
||||
|
||||
return this.genCalendar();
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -43,6 +43,10 @@ exports[`renders demo correctly 1`] = `
|
||||
<div class="van-cell__title"><span>自定义弹出位置</span></div><i class="van-icon van-icon-arrow van-cell__right-icon">
|
||||
<!----></i>
|
||||
</div>
|
||||
<div role="button" tabindex="0" class="van-cell van-cell--clickable">
|
||||
<div class="van-cell__title"><span>日期区间最大范围</span></div><i class="van-icon van-icon-arrow van-cell__right-icon">
|
||||
<!----></i>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="van-calendar" style="height: 500px;">
|
||||
|
||||
@@ -23,8 +23,8 @@ test('select event when type is single', async () => {
|
||||
propsData: {
|
||||
minDate,
|
||||
maxDate,
|
||||
poppable: false
|
||||
}
|
||||
poppable: false,
|
||||
},
|
||||
});
|
||||
|
||||
await later();
|
||||
@@ -43,8 +43,8 @@ test('select event when type is range', async () => {
|
||||
type: 'range',
|
||||
minDate,
|
||||
maxDate,
|
||||
poppable: false
|
||||
}
|
||||
poppable: false,
|
||||
},
|
||||
});
|
||||
|
||||
await later();
|
||||
@@ -68,8 +68,8 @@ test('should not trigger select event when click disabled day', async () => {
|
||||
propsData: {
|
||||
minDate,
|
||||
maxDate,
|
||||
poppable: false
|
||||
}
|
||||
poppable: false,
|
||||
},
|
||||
});
|
||||
|
||||
await later();
|
||||
@@ -87,8 +87,8 @@ test('confirm event when type is single', async () => {
|
||||
propsData: {
|
||||
minDate,
|
||||
maxDate,
|
||||
poppable: false
|
||||
}
|
||||
poppable: false,
|
||||
},
|
||||
});
|
||||
|
||||
await later();
|
||||
@@ -110,8 +110,8 @@ test('confirm event when type is range', async () => {
|
||||
type: 'range',
|
||||
minDate,
|
||||
maxDate,
|
||||
poppable: false
|
||||
}
|
||||
poppable: false,
|
||||
},
|
||||
});
|
||||
|
||||
await later();
|
||||
@@ -131,8 +131,8 @@ test('confirm event when type is range', async () => {
|
||||
test('default single date', async () => {
|
||||
const wrapper = mount(Calendar, {
|
||||
propsData: {
|
||||
poppable: false
|
||||
}
|
||||
poppable: false,
|
||||
},
|
||||
});
|
||||
|
||||
await later();
|
||||
@@ -145,8 +145,8 @@ test('default range date', async () => {
|
||||
const wrapper = mount(Calendar, {
|
||||
propsData: {
|
||||
type: 'range',
|
||||
poppable: false
|
||||
}
|
||||
poppable: false,
|
||||
},
|
||||
});
|
||||
|
||||
await later();
|
||||
@@ -163,8 +163,8 @@ test('reset method', async () => {
|
||||
minDate,
|
||||
maxDate,
|
||||
type: 'range',
|
||||
poppable: false
|
||||
}
|
||||
poppable: false,
|
||||
},
|
||||
});
|
||||
|
||||
await later();
|
||||
@@ -188,8 +188,8 @@ test('set show-confirm to false', async () => {
|
||||
maxDate,
|
||||
type: 'range',
|
||||
poppable: false,
|
||||
showConfirm: false
|
||||
}
|
||||
showConfirm: false,
|
||||
},
|
||||
});
|
||||
|
||||
await later();
|
||||
@@ -209,8 +209,8 @@ test('row-height prop', async () => {
|
||||
minDate,
|
||||
maxDate,
|
||||
poppable: false,
|
||||
rowHeight: 50
|
||||
}
|
||||
rowHeight: 50,
|
||||
},
|
||||
});
|
||||
|
||||
await later();
|
||||
@@ -243,8 +243,8 @@ test('formatter prop', async () => {
|
||||
}
|
||||
|
||||
return day;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await later();
|
||||
@@ -257,12 +257,12 @@ test('title & footer slot', async () => {
|
||||
propsData: {
|
||||
minDate,
|
||||
maxDate,
|
||||
poppable: false
|
||||
poppable: false,
|
||||
},
|
||||
scopedSlots: {
|
||||
title: () => 'Custom Title',
|
||||
footer: () => 'Custom Footer'
|
||||
}
|
||||
footer: () => 'Custom Footer',
|
||||
},
|
||||
});
|
||||
|
||||
await later();
|
||||
@@ -275,8 +275,8 @@ test('should reset when type changed', async () => {
|
||||
propsData: {
|
||||
minDate,
|
||||
maxDate,
|
||||
poppable: false
|
||||
}
|
||||
poppable: false,
|
||||
},
|
||||
});
|
||||
|
||||
await later();
|
||||
@@ -297,8 +297,8 @@ test('default-date prop in single type', async () => {
|
||||
minDate,
|
||||
maxDate,
|
||||
defaultDate: getNextDay(minDate),
|
||||
poppable: false
|
||||
}
|
||||
poppable: false,
|
||||
},
|
||||
});
|
||||
|
||||
await later();
|
||||
@@ -317,8 +317,8 @@ test('default-date prop in range type', async () => {
|
||||
type: 'range',
|
||||
minDate,
|
||||
maxDate,
|
||||
poppable: false
|
||||
}
|
||||
poppable: false,
|
||||
},
|
||||
});
|
||||
|
||||
await later();
|
||||
@@ -340,13 +340,13 @@ test('popup wrapper', async () => {
|
||||
const wrapper = mount(Calendar, {
|
||||
propsData: {
|
||||
minDate,
|
||||
maxDate
|
||||
maxDate,
|
||||
},
|
||||
listeners: {
|
||||
input(value) {
|
||||
wrapper.setProps({ value });
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await later();
|
||||
@@ -367,8 +367,8 @@ test('set show-mark prop to false', async () => {
|
||||
minDate,
|
||||
maxDate,
|
||||
showMark: false,
|
||||
poppable: false
|
||||
}
|
||||
poppable: false,
|
||||
},
|
||||
});
|
||||
|
||||
await later();
|
||||
@@ -382,8 +382,8 @@ test('color prop when type is single', async () => {
|
||||
minDate,
|
||||
maxDate,
|
||||
color: 'blue',
|
||||
poppable: false
|
||||
}
|
||||
poppable: false,
|
||||
},
|
||||
});
|
||||
|
||||
await later();
|
||||
@@ -399,8 +399,8 @@ test('color prop when type is range', async () => {
|
||||
minDate,
|
||||
maxDate,
|
||||
color: 'blue',
|
||||
poppable: false
|
||||
}
|
||||
poppable: false,
|
||||
},
|
||||
});
|
||||
|
||||
await later();
|
||||
@@ -414,12 +414,14 @@ test('should scroll to current month when show', async done => {
|
||||
type: 'range',
|
||||
minDate: new Date(2010, 0, 10),
|
||||
maxDate: new Date(2010, 11, 10),
|
||||
defaultDate: [new Date(2010, 3, 1), new Date(2010, 5, 1)]
|
||||
}
|
||||
defaultDate: [new Date(2010, 3, 1), new Date(2010, 5, 1)],
|
||||
},
|
||||
});
|
||||
|
||||
Element.prototype.scrollIntoView = function() {
|
||||
expect(this.parentNode).toEqual(wrapper.findAll('.van-calendar__month').at(3).element);
|
||||
expect(this.parentNode).toEqual(
|
||||
wrapper.findAll('.van-calendar__month').at(3).element
|
||||
);
|
||||
done();
|
||||
};
|
||||
|
||||
@@ -427,3 +429,24 @@ test('should scroll to current month when show', async done => {
|
||||
|
||||
await later();
|
||||
});
|
||||
|
||||
test('max-range prop', async () => {
|
||||
const wrapper = mount(Calendar, {
|
||||
propsData: {
|
||||
type: 'range',
|
||||
minDate,
|
||||
maxDate,
|
||||
maxRange: 1,
|
||||
poppable: false,
|
||||
},
|
||||
});
|
||||
|
||||
await later();
|
||||
|
||||
const days = wrapper.findAll('.van-calendar__day');
|
||||
days.at(15).trigger('click');
|
||||
days.at(18).trigger('click');
|
||||
wrapper.find('.van-calendar__confirm').trigger('click');
|
||||
|
||||
expect(wrapper.emitted('confirm')).toBeFalsy();
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { compareDay, compareMonth, getNextDay } from '../utils';
|
||||
import { compareDay, compareMonth, getNextDay, calcDateNum } from '../utils';
|
||||
|
||||
const date1 = new Date(2010, 0, 1);
|
||||
const date2 = new Date(2010, 0, 2);
|
||||
@@ -24,3 +24,8 @@ test('getNextDay', () => {
|
||||
expect(getNextDay(date1).getDate()).toEqual(2);
|
||||
expect(getNextDay(date2).getDate()).toEqual(3);
|
||||
});
|
||||
|
||||
test('calcDateNum', () => {
|
||||
expect(calcDateNum([date1, date2])).toEqual(2);
|
||||
expect(calcDateNum([date1, date3])).toEqual(32);
|
||||
});
|
||||
|
||||
@@ -42,3 +42,9 @@ export function getNextDay(date: Date) {
|
||||
|
||||
return date;
|
||||
}
|
||||
|
||||
export function calcDateNum(date: [Date, Date]) {
|
||||
const day1 = date[0].getTime();
|
||||
const day2 = date[1].getTime();
|
||||
return (day2 - day1) / (1000 * 60 * 60 * 24) + 1;
|
||||
}
|
||||
|
||||
+7
-7
@@ -2,7 +2,7 @@
|
||||
|
||||
### Install
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
import Vue from 'vue';
|
||||
import { Card } from 'vant';
|
||||
|
||||
@@ -19,7 +19,7 @@ Vue.use(Card);
|
||||
price="2.00"
|
||||
title="Title"
|
||||
desc="Description"
|
||||
thumb="https://img.yzcdn.cn/vant/t-thirt.jpg"
|
||||
thumb="https://img.yzcdn.cn/vant/ipad.jpeg"
|
||||
/>
|
||||
```
|
||||
|
||||
@@ -33,7 +33,7 @@ Vue.use(Card);
|
||||
title="Title"
|
||||
desc="Description"
|
||||
origin-price="10.00"
|
||||
thumb="https://img.yzcdn.cn/vant/t-thirt.jpg"
|
||||
thumb="https://img.yzcdn.cn/vant/ipad.jpeg"
|
||||
/>
|
||||
```
|
||||
|
||||
@@ -47,7 +47,7 @@ Use slot to custom content.
|
||||
title="Title"
|
||||
desc="Description"
|
||||
price="2.00"
|
||||
thumb="https://img.yzcdn.cn/vant/t-thirt.jpg"
|
||||
thumb="https://img.yzcdn.cn/vant/ipad.jpeg"
|
||||
>
|
||||
<div slot="tags">
|
||||
<van-tag plain type="danger">Tag</van-tag>
|
||||
@@ -70,9 +70,9 @@ Use slot to custom content.
|
||||
| title | Title | *string* | - |
|
||||
| desc | Description | *string* | - |
|
||||
| tag | Tag | *string* | - |
|
||||
| num | number | *string \| number* | - |
|
||||
| price | Price | *string \| number* | - |
|
||||
| origin-price | Origin price | *string \| number* | - |
|
||||
| num | number | *number \| string* | - |
|
||||
| price | Price | *number \| string* | - |
|
||||
| origin-price | Origin price | *number \| string* | - |
|
||||
| centered | Whether content vertical centered | *boolean* | `false` |
|
||||
| currency | Currency symbol | *string* | `¥` |
|
||||
| thumb-link | Thumb link URL | *string* | - |
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
### 引入
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
import Vue from 'vue';
|
||||
import { Card } from 'vant';
|
||||
|
||||
@@ -19,7 +19,7 @@ Vue.use(Card);
|
||||
price="2.00"
|
||||
desc="描述信息"
|
||||
title="商品标题"
|
||||
thumb="https://img.yzcdn.cn/vant/t-thirt.jpg"
|
||||
thumb="https://img.yzcdn.cn/vant/ipad.jpeg"
|
||||
/>
|
||||
```
|
||||
|
||||
@@ -34,7 +34,7 @@ Vue.use(Card);
|
||||
price="2.00"
|
||||
desc="描述信息"
|
||||
title="商品标题"
|
||||
thumb="https://img.yzcdn.cn/vant/t-thirt.jpg"
|
||||
thumb="https://img.yzcdn.cn/vant/ipad.jpeg"
|
||||
origin-price="10.00"
|
||||
/>
|
||||
```
|
||||
@@ -49,7 +49,7 @@ Vue.use(Card);
|
||||
price="2.00"
|
||||
desc="描述信息"
|
||||
title="商品标题"
|
||||
thumb="https://img.yzcdn.cn/vant/t-thirt.jpg"
|
||||
thumb="https://img.yzcdn.cn/vant/ipad.jpeg"
|
||||
>
|
||||
<div slot="tags">
|
||||
<van-tag plain type="danger">标签</van-tag>
|
||||
@@ -72,9 +72,9 @@ Vue.use(Card);
|
||||
| title | 标题 | *string* | - |
|
||||
| desc | 描述 | *string* | - |
|
||||
| tag | 图片角标 | *string* | - |
|
||||
| num | 商品数量 | *string \| number* | - |
|
||||
| price | 商品价格 | *string \| number* | - |
|
||||
| origin-price | 商品划线原价 | *string \| number* | - |
|
||||
| num | 商品数量 | *number \| string* | - |
|
||||
| price | 商品价格 | *number \| string* | - |
|
||||
| origin-price | 商品划线原价 | *number \| string* | - |
|
||||
| centered | 内容是否垂直居中 | *boolean* | `false` |
|
||||
| currency | 货币符号 | *string* | `¥` |
|
||||
| thumb-link | 点击左侧图片后跳转的链接地址 | *string* | - |
|
||||
|
||||
+9
-22
@@ -32,17 +32,10 @@
|
||||
>
|
||||
<template #tags>
|
||||
<div>
|
||||
<van-tag
|
||||
plain
|
||||
type="danger"
|
||||
style="margin-right: 5px;"
|
||||
>
|
||||
<van-tag plain type="danger" style="margin-right: 5px;">
|
||||
标签
|
||||
</van-tag>
|
||||
<van-tag
|
||||
plain
|
||||
type="danger"
|
||||
>
|
||||
<van-tag plain type="danger">
|
||||
标签
|
||||
</van-tag>
|
||||
</div>
|
||||
@@ -50,16 +43,10 @@
|
||||
|
||||
<template #footer>
|
||||
<div>
|
||||
<van-button
|
||||
round
|
||||
size="mini"
|
||||
>
|
||||
<van-button round size="mini">
|
||||
{{ $t('button') }}
|
||||
</van-button>
|
||||
<van-button
|
||||
round
|
||||
size="mini"
|
||||
>
|
||||
<van-button round size="mini">
|
||||
{{ $t('button') }}
|
||||
</van-button>
|
||||
</div>
|
||||
@@ -75,19 +62,19 @@ export default {
|
||||
'zh-CN': {
|
||||
title: '商品名称',
|
||||
discountInfo: '营销信息',
|
||||
customContent: '自定义内容'
|
||||
customContent: '自定义内容',
|
||||
},
|
||||
'en-US': {
|
||||
discountInfo: 'Discount Info',
|
||||
customContent: 'Custom Content'
|
||||
}
|
||||
customContent: 'Custom Content',
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
imageURL: 'https://img.yzcdn.cn/vant/t-thirt.jpg'
|
||||
imageURL: 'https://img.yzcdn.cn/vant/ipad.jpeg',
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
+6
-3
@@ -1,5 +1,8 @@
|
||||
// Utils
|
||||
import { createNamespace, isDef } from '../utils';
|
||||
import { emit, inherit } from '../utils/functional';
|
||||
|
||||
// Components
|
||||
import Tag from '../tag';
|
||||
import Image from '../image';
|
||||
|
||||
@@ -85,7 +88,7 @@ function Card(
|
||||
src={thumb}
|
||||
width="100%"
|
||||
height="100%"
|
||||
fit="contain"
|
||||
fit="cover"
|
||||
lazy-load={props.lazyLoad}
|
||||
/>
|
||||
)}
|
||||
@@ -206,8 +209,8 @@ Card.props = {
|
||||
originPrice: [Number, String],
|
||||
currency: {
|
||||
type: String,
|
||||
default: '¥'
|
||||
}
|
||||
default: '¥',
|
||||
},
|
||||
};
|
||||
|
||||
export default createComponent<CardProps, CardEvents>(Card);
|
||||
|
||||
@@ -5,7 +5,7 @@ exports[`renders demo correctly 1`] = `
|
||||
<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" style="width: 100%; height: 100%;"><img src="https://img.yzcdn.cn/vant/ipad.jpeg" class="van-image__img" style="object-fit: cover;">
|
||||
<div class="van-image__loading"><i class="van-icon van-icon-photo-o van-image__loading-icon">
|
||||
<!----></i></div>
|
||||
</div>
|
||||
@@ -28,7 +28,7 @@ exports[`renders demo correctly 1`] = `
|
||||
<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" style="width: 100%; height: 100%;"><img src="https://img.yzcdn.cn/vant/ipad.jpeg" class="van-image__img" style="object-fit: cover;">
|
||||
<div class="van-image__loading"><i class="van-icon van-icon-photo-o van-image__loading-icon">
|
||||
<!----></i></div>
|
||||
</div>
|
||||
@@ -53,7 +53,7 @@ exports[`renders demo correctly 1`] = `
|
||||
<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" style="width: 100%; height: 100%;"><img src="https://img.yzcdn.cn/vant/ipad.jpeg" class="van-image__img" style="object-fit: cover;">
|
||||
<div class="van-image__loading"><i class="van-icon van-icon-photo-o van-image__loading-icon">
|
||||
<!----></i></div>
|
||||
</div>
|
||||
|
||||
+21
-21
@@ -6,16 +6,16 @@ test('click event', () => {
|
||||
const wrapper = mount(Card, {
|
||||
context: {
|
||||
on: {
|
||||
click: onClick
|
||||
}
|
||||
}
|
||||
click: onClick,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
wrapper.trigger('click');
|
||||
|
||||
expect(onClick).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
isTrusted: expect.any(Boolean)
|
||||
isTrusted: expect.any(Boolean),
|
||||
})
|
||||
);
|
||||
});
|
||||
@@ -24,20 +24,20 @@ test('click-thumb event', () => {
|
||||
const onClickThumb = jest.fn();
|
||||
const wrapper = mount(Card, {
|
||||
propsData: {
|
||||
thumb: 'xx'
|
||||
thumb: 'xx',
|
||||
},
|
||||
context: {
|
||||
on: {
|
||||
'click-thumb': onClickThumb
|
||||
}
|
||||
}
|
||||
'click-thumb': onClickThumb,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
wrapper.find('.van-card__thumb').trigger('click');
|
||||
|
||||
expect(onClickThumb).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
isTrusted: expect.any(Boolean)
|
||||
isTrusted: expect.any(Boolean),
|
||||
})
|
||||
);
|
||||
});
|
||||
@@ -46,8 +46,8 @@ test('render price & num slot', () => {
|
||||
const wrapper = mount(Card, {
|
||||
scopedSlots: {
|
||||
num: () => 'Custom Num',
|
||||
price: () => 'Custom Price'
|
||||
}
|
||||
price: () => 'Custom Price',
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
@@ -56,8 +56,8 @@ test('render price & num slot', () => {
|
||||
test('render origin-price slot', () => {
|
||||
const wrapper = mount(Card, {
|
||||
scopedSlots: {
|
||||
'origin-price': () => 'Custom Origin Price'
|
||||
}
|
||||
'origin-price': () => 'Custom Origin Price',
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
@@ -66,8 +66,8 @@ test('render origin-price slot', () => {
|
||||
test('render bottom slot', () => {
|
||||
const wrapper = mount(Card, {
|
||||
scopedSlots: {
|
||||
bottom: () => 'Custom Bottom'
|
||||
}
|
||||
bottom: () => 'Custom Bottom',
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
@@ -77,8 +77,8 @@ test('render thumb & tag slot', () => {
|
||||
const wrapper = mount(Card, {
|
||||
scopedSlots: {
|
||||
tag: () => 'Custom Tag',
|
||||
thumb: () => 'Custom Thumb'
|
||||
}
|
||||
thumb: () => 'Custom Thumb',
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
@@ -88,8 +88,8 @@ test('render title & desc slot', () => {
|
||||
const wrapper = mount(Card, {
|
||||
scopedSlots: {
|
||||
title: () => 'Custom Title',
|
||||
desc: () => 'Custom desc'
|
||||
}
|
||||
desc: () => 'Custom desc',
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
@@ -99,8 +99,8 @@ test('render price & price-top slot', () => {
|
||||
const wrapper = mount(Card, {
|
||||
scopedSlots: {
|
||||
price: () => 'Custom Price',
|
||||
'price-top': () => 'Custom Price-top'
|
||||
}
|
||||
'price-top': () => 'Custom Price-top',
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Utils
|
||||
import { createNamespace } from '../utils';
|
||||
import { inherit } from '../utils/functional';
|
||||
import { BORDER_TOP_BOTTOM } from '../utils/constant';
|
||||
@@ -24,7 +25,10 @@ function CellGroup(
|
||||
ctx: RenderContext<CellGroupProps>
|
||||
) {
|
||||
const Group = (
|
||||
<div class={[bem(), { [BORDER_TOP_BOTTOM]: props.border }]} {...inherit(ctx, true)}>
|
||||
<div
|
||||
class={[bem(), { [BORDER_TOP_BOTTOM]: props.border }]}
|
||||
{...inherit(ctx, true)}
|
||||
>
|
||||
{slots.default?.()}
|
||||
</div>
|
||||
);
|
||||
@@ -32,7 +36,9 @@ function CellGroup(
|
||||
if (props.title || slots.title) {
|
||||
return (
|
||||
<div>
|
||||
<div class={bem('title')}>{slots.title ? slots.title() : props.title}</div>
|
||||
<div class={bem('title')}>
|
||||
{slots.title ? slots.title() : props.title}
|
||||
</div>
|
||||
{Group}
|
||||
</div>
|
||||
);
|
||||
@@ -45,8 +51,8 @@ CellGroup.props = {
|
||||
title: String,
|
||||
border: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
default: true,
|
||||
},
|
||||
};
|
||||
|
||||
export default createComponent<CellGroupProps>(CellGroup);
|
||||
|
||||
+6
-5
@@ -2,11 +2,12 @@
|
||||
|
||||
### Install
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
import Vue from 'vue';
|
||||
import { Cell, CellGroup } from 'vant';
|
||||
|
||||
Vue.use(Cell).use(CellGroup);
|
||||
Vue.use(Cell);
|
||||
Vue.use(CellGroup);
|
||||
```
|
||||
|
||||
## Usage
|
||||
@@ -114,8 +115,8 @@ Vue.use(Cell).use(CellGroup);
|
||||
| Attribute | Description | Type | Default |
|
||||
|------|------|------|------|
|
||||
| icon | Left Icon | *string* | - |
|
||||
| title | Title | *string \| number* | - |
|
||||
| value | Right text | *string \| number* | - |
|
||||
| title | Title | *number \| string* | - |
|
||||
| value | Right text | *number \| string* | - |
|
||||
| label | Description below the title | *string* | - |
|
||||
| size | Size,can be set to `large` | *string* | - |
|
||||
| border | Whether to show inner border | *boolean* | `true` |
|
||||
@@ -126,7 +127,7 @@ Vue.use(Cell).use(CellGroup);
|
||||
| clickable | Whether to show click feedback when clicked | *boolean* | `false` |
|
||||
| is-link | Whether to show link icon | *boolean* | `false` |
|
||||
| required | Whether to show required mark | *boolean* | `false` |
|
||||
| arrow-direction | Can be set to `left` `up` `down` | *string* | - |
|
||||
| arrow-direction | Can be set to `left` `up` `down` | *string* | `right` |
|
||||
| title-style | Title style | *any* | - |
|
||||
| title-class | Title className | *any* | - |
|
||||
| value-class | Value className | *any* | - |
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
|
||||
### 引入
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
import Vue from 'vue';
|
||||
import { Cell, CellGroup } from 'vant';
|
||||
|
||||
Vue.use(Cell).use(CellGroup);
|
||||
Vue.use(Cell);
|
||||
Vue.use(CellGroup);
|
||||
```
|
||||
|
||||
## 代码演示
|
||||
@@ -124,9 +125,9 @@ Vue.use(Cell).use(CellGroup);
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|------|------|------|------|
|
||||
| icon | 左侧图标名称或图片链接,可选值见 [Icon 组件](#/zh-CN/icon) | *string* | - |
|
||||
| title | 左侧标题 | *string \| number* | - |
|
||||
| value | 右侧内容 | *string \| number* | - |
|
||||
| icon | 左侧 [图标名称](#/zh-CN/icon) 或图片链接 | *string* | - |
|
||||
| title | 左侧标题 | *number \| string* | - |
|
||||
| value | 右侧内容 | *number \| string* | - |
|
||||
| label | 标题下方的描述信息 | *string* | - |
|
||||
| size | 单元格大小,可选值为 `large` | *string* | - |
|
||||
| url | 点击后跳转的链接地址 | *string* | - |
|
||||
@@ -137,7 +138,7 @@ Vue.use(Cell).use(CellGroup);
|
||||
| is-link | 是否展示右侧箭头并开启点击反馈 | *boolean* | `false` |
|
||||
| required | 是否显示表单必填星号 | *boolean* | `false` |
|
||||
| center | 是否使内容垂直居中 | *boolean* | `false` |
|
||||
| arrow-direction | 箭头方向,可选值为 `left` `up` `down` | *string* | - |
|
||||
| arrow-direction | 箭头方向,可选值为 `left` `up` `down` | *string* | `right` |
|
||||
| title-style | 左侧标题额外样式 | *any* | - |
|
||||
| title-class | 左侧标题额外类名 | *any* | - |
|
||||
| value-class | 右侧内容额外类名 | *any* | - |
|
||||
|
||||
+27
-8
@@ -3,13 +3,22 @@
|
||||
<demo-block :title="$t('basicUsage')">
|
||||
<van-cell-group>
|
||||
<van-cell :title="$t('cell')" :value="$t('content')" />
|
||||
<van-cell :title="$t('cell')" :value="$t('content')" :label="$t('desc')" />
|
||||
<van-cell
|
||||
:title="$t('cell')"
|
||||
:value="$t('content')"
|
||||
:label="$t('desc')"
|
||||
/>
|
||||
</van-cell-group>
|
||||
</demo-block>
|
||||
|
||||
<demo-block :title="$t('largeSize')">
|
||||
<van-cell :title="$t('cell')" :value="$t('content')" size="large" />
|
||||
<van-cell :title="$t('cell')" :value="$t('content')" size="large" :label="$t('desc')" />
|
||||
<van-cell
|
||||
:title="$t('cell')"
|
||||
:value="$t('content')"
|
||||
size="large"
|
||||
:label="$t('desc')"
|
||||
/>
|
||||
</demo-block>
|
||||
|
||||
<demo-block :title="$t('showIcon')">
|
||||
@@ -23,7 +32,12 @@
|
||||
<demo-block :title="$t('showArrow')">
|
||||
<van-cell :title="$t('cell')" is-link />
|
||||
<van-cell :title="$t('cell')" is-link :value="$t('content')" />
|
||||
<van-cell :title="$t('cell')" is-link arrow-direction="down" :value="$t('content')" />
|
||||
<van-cell
|
||||
:title="$t('cell')"
|
||||
is-link
|
||||
arrow-direction="down"
|
||||
:value="$t('content')"
|
||||
/>
|
||||
</demo-block>
|
||||
|
||||
<demo-block :title="$t('router')">
|
||||
@@ -56,7 +70,12 @@
|
||||
</demo-block>
|
||||
|
||||
<demo-block :title="$t('verticalCenter')">
|
||||
<van-cell center :title="$t('cell')" :value="$t('content')" :label="$t('desc')" />
|
||||
<van-cell
|
||||
center
|
||||
:title="$t('cell')"
|
||||
:value="$t('content')"
|
||||
:label="$t('desc')"
|
||||
/>
|
||||
</demo-block>
|
||||
</demo-section>
|
||||
</template>
|
||||
@@ -76,7 +95,7 @@ export default {
|
||||
urlRoute: 'URL 跳转',
|
||||
vueRoute: '路由跳转',
|
||||
useSlots: '使用插槽',
|
||||
verticalCenter: '垂直居中'
|
||||
verticalCenter: '垂直居中',
|
||||
},
|
||||
'en-US': {
|
||||
cell: 'Cell title',
|
||||
@@ -90,9 +109,9 @@ export default {
|
||||
urlRoute: 'URL',
|
||||
vueRoute: 'Vue Router',
|
||||
useSlots: 'Use Slots',
|
||||
verticalCenter: 'Vertical center'
|
||||
}
|
||||
}
|
||||
verticalCenter: 'Vertical center',
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
@import '../style/var';
|
||||
@import "../style/mixins/hairline";
|
||||
@import '../style/mixins/hairline';
|
||||
|
||||
.van-cell {
|
||||
position: relative;
|
||||
|
||||
+6
-3
@@ -1,7 +1,10 @@
|
||||
// Utils
|
||||
import { createNamespace, isDef } from '../utils';
|
||||
import { cellProps, SharedCellProps } from './shared';
|
||||
import { emit, inherit } from '../utils/functional';
|
||||
import { routeProps, RouteProps, functionalRoute } from '../utils/router';
|
||||
import { cellProps, SharedCellProps } from './shared';
|
||||
|
||||
// Components
|
||||
import Icon from '../icon';
|
||||
|
||||
// Types
|
||||
@@ -109,7 +112,7 @@ function Cell(
|
||||
clickable,
|
||||
center: props.center,
|
||||
required: props.required,
|
||||
borderless: !props.border
|
||||
borderless: !props.border,
|
||||
};
|
||||
|
||||
if (size) {
|
||||
@@ -135,7 +138,7 @@ function Cell(
|
||||
|
||||
Cell.props = {
|
||||
...cellProps,
|
||||
...routeProps
|
||||
...routeProps,
|
||||
};
|
||||
|
||||
export default createComponent<CellProps, CellEvents, CellSlots>(Cell);
|
||||
|
||||
+3
-3
@@ -14,7 +14,7 @@ export type SharedCellProps = {
|
||||
value?: string | number;
|
||||
label?: string | number;
|
||||
arrowDirection?: 'up' | 'down' | 'left' | 'right';
|
||||
}
|
||||
};
|
||||
|
||||
export const cellProps = {
|
||||
icon: String,
|
||||
@@ -33,6 +33,6 @@ export const cellProps = {
|
||||
arrowDirection: String,
|
||||
border: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
default: true,
|
||||
},
|
||||
};
|
||||
|
||||
+12
-12
@@ -7,9 +7,9 @@ test('click event', () => {
|
||||
const wrapper = mount(Cell, {
|
||||
context: {
|
||||
on: {
|
||||
click
|
||||
}
|
||||
}
|
||||
click,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
wrapper.trigger('click');
|
||||
@@ -20,8 +20,8 @@ test('arrow direction', () => {
|
||||
const wrapper = mount(Cell, {
|
||||
propsData: {
|
||||
isLink: true,
|
||||
arrowDirection: 'down'
|
||||
}
|
||||
arrowDirection: 'down',
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
@@ -38,8 +38,8 @@ test('render slot', () => {
|
||||
</cell>
|
||||
`,
|
||||
components: {
|
||||
Cell
|
||||
}
|
||||
Cell,
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
@@ -50,9 +50,9 @@ test('title-style prop', () => {
|
||||
propsData: {
|
||||
title: 'title',
|
||||
titleStyle: {
|
||||
color: 'red'
|
||||
}
|
||||
}
|
||||
color: 'red',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
@@ -61,8 +61,8 @@ test('title-style prop', () => {
|
||||
test('CellGroup title slot', () => {
|
||||
const wrapper = mount(CellGroup, {
|
||||
scopedSlots: {
|
||||
title: () => 'CustomTitle'
|
||||
}
|
||||
title: () => 'CustomTitle',
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
|
||||
@@ -7,20 +7,20 @@ export default createComponent({
|
||||
mixins: [ParentMixin('vanCheckbox')],
|
||||
|
||||
props: {
|
||||
max: Number,
|
||||
max: [Number, String],
|
||||
disabled: Boolean,
|
||||
iconSize: [Number, String],
|
||||
checkedColor: String,
|
||||
value: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
|
||||
watch: {
|
||||
value(val) {
|
||||
this.$emit('change', val);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
@@ -38,10 +38,10 @@ export default createComponent({
|
||||
|
||||
const names = children.map(item => item.name);
|
||||
this.$emit('input', names);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
render() {
|
||||
return <div class={bem()}>{this.slots()}</div>;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
|
||||
### Install
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
import Vue from 'vue';
|
||||
import { Checkbox, CheckboxGroup } from 'vant';
|
||||
|
||||
Vue.use(Checkbox).use(CheckboxGroup);
|
||||
Vue.use(Checkbox);
|
||||
Vue.use(CheckboxGroup);
|
||||
```
|
||||
|
||||
## Usage
|
||||
@@ -17,7 +18,7 @@ Vue.use(Checkbox).use(CheckboxGroup);
|
||||
<van-checkbox v-model="checked">Checkbox</van-checkbox>
|
||||
```
|
||||
|
||||
```javascript
|
||||
```js
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
@@ -96,7 +97,7 @@ When Checkboxes are inside a CheckboxGroup, the checked checkboxes's name is an
|
||||
</van-checkbox-group>
|
||||
```
|
||||
|
||||
```javascript
|
||||
```js
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
@@ -192,7 +193,7 @@ export default {
|
||||
| disabled | Disable checkbox | *boolean* | `false` |
|
||||
| label-disabled | Whether to disable label click | *boolean* | `false` |
|
||||
| label-position | Can be set to `left` | *string* | `right` |
|
||||
| icon-size | Icon size | *string \| number* | `20px` |
|
||||
| icon-size | Icon size | *number \| string* | `20px` |
|
||||
| checked-color | Checked color | *string* | `#1989fa` | - |
|
||||
| bind-group `v2.2.4` | Whether to bind with CheckboxGroup | *boolean* | `true` |
|
||||
|
||||
@@ -201,9 +202,9 @@ export default {
|
||||
| Attribute | Description | Type | Default |
|
||||
|------|------|------|------|
|
||||
| v-model | Names of all checked checkboxes | *any[]* | - |
|
||||
| max | Maximum amount of checked options | *number* | `0`(Unlimited) |
|
||||
| max | Maximum amount of checked options | *number \| string* | `0`(Unlimited) |
|
||||
| disabled | Disable all checkboxes | *boolean* | `false` |
|
||||
| icon-size `v2.2.3` | Icon size of all checkboxes | *string \| number* | `20px` |
|
||||
| icon-size `v2.2.3` | Icon size of all checkboxes | *number \| string* | `20px` |
|
||||
| checked-color `v2.2.3` | Checked color of all checkboxes | *string* | `#1989fa` | - |
|
||||
|
||||
### Checkbox Events
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
|
||||
### 引入
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
import Vue from 'vue';
|
||||
import { Checkbox, CheckboxGroup } from 'vant';
|
||||
|
||||
Vue.use(Checkbox).use(CheckboxGroup);
|
||||
Vue.use(Checkbox);
|
||||
Vue.use(CheckboxGroup);
|
||||
```
|
||||
|
||||
## 代码演示
|
||||
@@ -19,7 +20,7 @@ Vue.use(Checkbox).use(CheckboxGroup);
|
||||
<van-checkbox v-model="checked">复选框</van-checkbox>
|
||||
```
|
||||
|
||||
```javascript
|
||||
```js
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
@@ -106,7 +107,7 @@ export default {
|
||||
</van-checkbox-group>
|
||||
```
|
||||
|
||||
```javascript
|
||||
```js
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
@@ -208,7 +209,7 @@ export default {
|
||||
| disabled | 是否禁用复选框 | *boolean* | `false` |
|
||||
| label-disabled | 是否禁用复选框文本点击 | *boolean* | `false` |
|
||||
| label-position | 文本位置,可选值为 `left` | *string* | `right` |
|
||||
| icon-size | 图标大小,默认单位为`px` | *string \| number* | `20px` |
|
||||
| icon-size | 图标大小,默认单位为`px` | *number \| string* | `20px` |
|
||||
| checked-color | 选中状态颜色 | *string* | `#1989fa` |
|
||||
| bind-group `v2.2.4` | 是否与复选框组绑定 | *boolean* | `true` |
|
||||
|
||||
@@ -218,8 +219,8 @@ export default {
|
||||
|------|------|------|------|
|
||||
| v-model | 所有选中项的标识符 | *any[]* | - |
|
||||
| disabled | 是否禁用所有复选框 | *boolean* | `false` |
|
||||
| max | 最大可选数,0 为无限制 | *number* | `0` |
|
||||
| icon-size `v2.2.3` | 所有复选框的图标大小,默认单位为`px` | *string \| number* | `20px` |
|
||||
| max | 最大可选数,0 为无限制 | *number \| string* | `0` |
|
||||
| icon-size `v2.2.3` | 所有复选框的图标大小,默认单位为`px` | *number \| string* | `20px` |
|
||||
| checked-color `v2.2.3` | 所有复选框的选中状态颜色 | *string* | `#1989fa` |
|
||||
|
||||
### Checkbox Events
|
||||
@@ -244,7 +245,7 @@ export default {
|
||||
|
||||
### CheckboxGroup 方法
|
||||
|
||||
通过 [ref](https://cn.vuejs.org/v2/api/#ref) 可以获取到 CheckboxGroup 实例并调用实例方法
|
||||
通过 ref 可以获取到 CheckboxGroup 实例并调用实例方法,详见 [组件实例方法](#/zh-CN/quickstart#zu-jian-shi-li-fang-fa)
|
||||
|
||||
| 方法名 | 说明 | 参数 | 返回值 |
|
||||
|------|------|------|------|
|
||||
@@ -252,7 +253,7 @@ export default {
|
||||
|
||||
### Checkbox 方法
|
||||
|
||||
通过 [ref](https://cn.vuejs.org/v2/api/#ref) 可以获取到 Checkbox 实例并调用实例方法
|
||||
通过 ref 可以获取到 Checkbox 实例并调用实例方法,详见 [组件实例方法](#/zh-CN/quickstart#zu-jian-shi-li-fang-fa)
|
||||
|
||||
| 方法名 | 说明 | 参数 | 返回值 |
|
||||
|------|------|------|------|
|
||||
|
||||
+15
-15
@@ -41,7 +41,7 @@
|
||||
<van-checkbox v-model="checkbox3">
|
||||
{{ $t('customIcon') }}
|
||||
<template #icon="{ checked }">
|
||||
<img :src="checked ? activeIcon : inactiveIcon">
|
||||
<img :src="checked ? activeIcon : inactiveIcon" />
|
||||
</template>
|
||||
</van-checkbox>
|
||||
</demo-block>
|
||||
@@ -70,8 +70,12 @@
|
||||
</van-checkbox-group>
|
||||
|
||||
<div class="demo-checkbox-buttons">
|
||||
<van-button type="primary" @click="checkAll">{{ $t('checkAll') }}</van-button>
|
||||
<van-button type="info" @click="toggleAll">{{ $t('inverse') }}</van-button>
|
||||
<van-button type="primary" @click="checkAll">
|
||||
{{ $t('checkAll') }}
|
||||
</van-button>
|
||||
<van-button type="info" @click="toggleAll">
|
||||
{{ $t('inverse') }}
|
||||
</van-button>
|
||||
</div>
|
||||
</demo-block>
|
||||
|
||||
@@ -110,7 +114,7 @@ export default {
|
||||
toggleAll: '全选与反选',
|
||||
checkAll: '全选',
|
||||
inverse: '反选',
|
||||
disabledLabelClick: '禁用文本点击'
|
||||
disabledLabelClick: '禁用文本点击',
|
||||
},
|
||||
'en-US': {
|
||||
checkbox: 'Checkbox',
|
||||
@@ -124,8 +128,8 @@ export default {
|
||||
toggleAll: 'Toggle All',
|
||||
checkAll: 'Check All',
|
||||
inverse: 'Inverse',
|
||||
disabledLabelClick: 'Disable the click event of label'
|
||||
}
|
||||
disabledLabelClick: 'Disable the click event of label',
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
@@ -136,17 +140,13 @@ export default {
|
||||
checkboxShape: true,
|
||||
checkboxLabel: true,
|
||||
checboxIcon: true,
|
||||
list: [
|
||||
'a',
|
||||
'b',
|
||||
'c'
|
||||
],
|
||||
list: ['a', 'b', 'c'],
|
||||
result: ['a', 'b'],
|
||||
result2: [],
|
||||
result3: [],
|
||||
checkAllResult: [],
|
||||
activeIcon: 'https://img.yzcdn.cn/vant/user-active.png',
|
||||
inactiveIcon: 'https://img.yzcdn.cn/vant/user-inactive.png'
|
||||
inactiveIcon: 'https://img.yzcdn.cn/vant/user-inactive.png',
|
||||
};
|
||||
},
|
||||
|
||||
@@ -161,13 +161,13 @@ export default {
|
||||
|
||||
toggleAll() {
|
||||
this.$refs.group.toggleAll();
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
@import "../../style/var";
|
||||
@import '../../style/var';
|
||||
|
||||
.demo-checkbox {
|
||||
background: @white;
|
||||
|
||||
+16
-11
@@ -4,16 +4,21 @@ import { CheckboxMixin } from '../mixins/checkbox';
|
||||
const [createComponent, bem] = createNamespace('checkbox');
|
||||
|
||||
export default createComponent({
|
||||
mixins: [CheckboxMixin({
|
||||
bem,
|
||||
role: 'checkbox',
|
||||
parent: 'vanCheckbox'
|
||||
})],
|
||||
mixins: [
|
||||
CheckboxMixin({
|
||||
bem,
|
||||
role: 'checkbox',
|
||||
parent: 'vanCheckbox',
|
||||
}),
|
||||
],
|
||||
|
||||
computed: {
|
||||
checked: {
|
||||
get() {
|
||||
return this.parent ? this.parent.value.indexOf(this.name) !== -1 : this.value;
|
||||
if (this.parent) {
|
||||
return this.parent.value.indexOf(this.name) !== -1;
|
||||
}
|
||||
return this.value;
|
||||
},
|
||||
|
||||
set(val) {
|
||||
@@ -22,14 +27,14 @@ export default createComponent({
|
||||
} else {
|
||||
this.$emit('input', val);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
watch: {
|
||||
value(val) {
|
||||
this.$emit('change', val);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
@@ -67,6 +72,6 @@ export default createComponent({
|
||||
parent.$emit('input', value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
width: 1.25em;
|
||||
height: 1.25em;
|
||||
color: transparent;
|
||||
font-size: .8em;
|
||||
font-size: 0.8em;
|
||||
line-height: inherit;
|
||||
text-align: center;
|
||||
border: 1px solid @checkbox-border-color;
|
||||
|
||||
@@ -108,7 +108,11 @@ exports[`renders demo correctly 1`] = `
|
||||
<!----></i></div><span class="van-checkbox__label">复选框 c</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="demo-checkbox-buttons"><button class="van-button van-button--primary van-button--normal"><span class="van-button__text">全选</span></button> <button class="van-button van-button--info van-button--normal"><span class="van-button__text">反选</span></button></div>
|
||||
<div class="demo-checkbox-buttons"><button class="van-button van-button--primary van-button--normal"><span class="van-button__text">
|
||||
全选
|
||||
</span></button> <button class="van-button van-button--info van-button--normal"><span class="van-button__text">
|
||||
反选
|
||||
</span></button></div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="van-checkbox-group">
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
import Vue from 'vue';
|
||||
import Checkbox from '..';
|
||||
import CheckboxGroup from '../../checkbox-group';
|
||||
import { mount, later } from '../../../test';
|
||||
|
||||
Vue.use(Checkbox);
|
||||
Vue.use(CheckboxGroup);
|
||||
|
||||
test('switch checkbox', async () => {
|
||||
const wrapper = mount(Checkbox);
|
||||
|
||||
@@ -25,8 +20,8 @@ test('switch checkbox', async () => {
|
||||
test('disabled', () => {
|
||||
const wrapper = mount(Checkbox, {
|
||||
propsData: {
|
||||
disabled: true
|
||||
}
|
||||
disabled: true,
|
||||
},
|
||||
});
|
||||
|
||||
wrapper.find('.van-checkbox__icon').trigger('click');
|
||||
@@ -36,11 +31,11 @@ test('disabled', () => {
|
||||
test('label disabled', () => {
|
||||
const wrapper = mount(Checkbox, {
|
||||
scopedSlots: {
|
||||
default: () => 'Label'
|
||||
default: () => 'Label',
|
||||
},
|
||||
propsData: {
|
||||
labelDisabled: true
|
||||
}
|
||||
labelDisabled: true,
|
||||
},
|
||||
});
|
||||
|
||||
wrapper.find('.van-checkbox__label').trigger('click');
|
||||
@@ -59,9 +54,9 @@ test('checkbox group', async () => {
|
||||
`,
|
||||
data() {
|
||||
return {
|
||||
result: []
|
||||
result: [],
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const icons = wrapper.findAll('.van-checkbox__icon');
|
||||
@@ -82,8 +77,8 @@ test('click event', () => {
|
||||
const onClick = jest.fn();
|
||||
const wrapper = mount(Checkbox, {
|
||||
listeners: {
|
||||
click: onClick
|
||||
}
|
||||
click: onClick,
|
||||
},
|
||||
});
|
||||
|
||||
wrapper.trigger('click');
|
||||
@@ -97,11 +92,11 @@ test('click event', () => {
|
||||
test('label-position prop', () => {
|
||||
const wrapper = mount(Checkbox, {
|
||||
scopedSlots: {
|
||||
default: () => 'Label'
|
||||
default: () => 'Label',
|
||||
},
|
||||
propsData: {
|
||||
labelPosition: 'left'
|
||||
}
|
||||
labelPosition: 'left',
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
@@ -114,7 +109,7 @@ test('icon-size prop', () => {
|
||||
<van-checkbox>label</van-checkbox>
|
||||
<van-checkbox icon-size="5rem">label</van-checkbox>
|
||||
</van-checkbox-group>
|
||||
`
|
||||
`,
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
@@ -127,7 +122,7 @@ test('checked-color prop', () => {
|
||||
<van-checkbox name="a" :value="true">label</van-checkbox>
|
||||
<van-checkbox name="b" :value="true" checked-color="white">label</van-checkbox>
|
||||
</van-checkbox-group>
|
||||
`
|
||||
`,
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
@@ -145,9 +140,9 @@ test('bind-group prop', async () => {
|
||||
return {
|
||||
value: false,
|
||||
result: [],
|
||||
list: ['a', 'b', 'c']
|
||||
list: ['a', 'b', 'c'],
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const icons = wrapper.findAll('.van-checkbox__icon');
|
||||
@@ -168,14 +163,14 @@ test('toggleAll method', async () => {
|
||||
`,
|
||||
data() {
|
||||
return {
|
||||
result: ['a']
|
||||
result: ['a'],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
toggleAll(checked) {
|
||||
this.$refs.group.toggleAll(checked);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
wrapper.vm.toggleAll();
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
### Install
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
import Vue from 'vue';
|
||||
import { Circle } from 'vant';
|
||||
|
||||
@@ -22,7 +22,7 @@ Vue.use(Circle);
|
||||
/>
|
||||
```
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
@@ -70,7 +70,7 @@ export default {
|
||||
/>
|
||||
```
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
@@ -113,14 +113,14 @@ export default {
|
||||
| Attribute | Description | Type | Default |
|
||||
|------|------|------|------|
|
||||
| v-model | Current rate | *number* | - |
|
||||
| rate | Target rate | *number* | `100` |
|
||||
| size | Circle size | *string \| number* | `100px` |
|
||||
| rate | Target rate | *number \| string* | `100` |
|
||||
| size | Circle size | *number \| string* | `100px` |
|
||||
| color `v2.1.4` | Progress color, passing object to render gradient | *string \| object* | `#1989fa` |
|
||||
| layer-color | Layer color | *string* | `#fff` |
|
||||
| layer-color | Layer color | *string* | `white` |
|
||||
| fill | Fill color | *string* | `none` |
|
||||
| speed | Animate speed(rate/s)| *number* | `0` |
|
||||
| speed | Animate speed(rate/s)| *number \| string* | `0` |
|
||||
| text | Text | *string* | - |
|
||||
| stroke-width | Stroke width | *number* | `40` |
|
||||
| stroke-width | Stroke width | *number \| string* | `40` |
|
||||
| stroke-linecap `v2.2.15` | Stroke linecap,can be set to `sqaure` `butt` | *string* | `round` |
|
||||
| clockwise | Whether to be clockwise | *boolean* | `true` |
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
### 引入
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
import Vue from 'vue';
|
||||
import { Circle } from 'vant';
|
||||
|
||||
@@ -24,7 +24,7 @@ Vue.use(Circle);
|
||||
/>
|
||||
```
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
@@ -78,7 +78,7 @@ export default {
|
||||
/>
|
||||
```
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
@@ -125,14 +125,14 @@ export default {
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|------|------|------|------|
|
||||
| v-model | 当前进度 | *number* | - |
|
||||
| rate | 目标进度 | *number* | `100` |
|
||||
| size | 圆环直径,默认单位为 `px` | *string \| number* | `100px` |
|
||||
| rate | 目标进度 | *number \| string* | `100` |
|
||||
| size | 圆环直径,默认单位为 `px` | *number \| string* | `100px` |
|
||||
| color `v2.1.4` | 进度条颜色,传入对象格式可以定义渐变色 | *string \| object* | `#1989fa` |
|
||||
| layer-color | 轨道颜色 | *string* | `#fff` |
|
||||
| layer-color | 轨道颜色 | *string* | `white` |
|
||||
| fill | 填充颜色 | *string* | `none` |
|
||||
| speed | 动画速度(单位为 rate/s)| *number* | `0` |
|
||||
| speed | 动画速度(单位为 rate/s)| *number \| string* | `0` |
|
||||
| text | 文字 | *string* | - |
|
||||
| stroke-width | 进度条宽度 | *number* | `40` |
|
||||
| stroke-width | 进度条宽度 | *number \| string* | `40` |
|
||||
| stroke-linecap `v2.2.15` | 进度条端点的形状,可选值为`sqaure` `butt` | *string* | `round` |
|
||||
| clockwise | 是否顺时针增加 | *boolean* | `true` |
|
||||
|
||||
|
||||
@@ -58,12 +58,7 @@
|
||||
</demo-block>
|
||||
|
||||
<div style="margin-top: 15px;">
|
||||
<van-button
|
||||
:text="$t('add')"
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="add"
|
||||
/>
|
||||
<van-button :text="$t('add')" type="primary" size="small" @click="add" />
|
||||
<van-button
|
||||
:text="$t('decrease')"
|
||||
type="danger"
|
||||
@@ -85,7 +80,7 @@ export default {
|
||||
customStyle: '样式定制',
|
||||
customColor: '颜色定制',
|
||||
customWidth: '宽度定制',
|
||||
counterClockwise: '逆时针'
|
||||
counterClockwise: '逆时针',
|
||||
},
|
||||
'en-US': {
|
||||
gradient: 'Gradient',
|
||||
@@ -93,8 +88,8 @@ export default {
|
||||
customStyle: 'Custom Style',
|
||||
customColor: 'Custom Color',
|
||||
customWidth: 'Custom Width',
|
||||
counterClockwise: 'Counter Clockwise'
|
||||
}
|
||||
counterClockwise: 'Counter Clockwise',
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
@@ -106,8 +101,8 @@ export default {
|
||||
currentRate4: 70,
|
||||
gradientColor: {
|
||||
'0%': '#3fecff',
|
||||
'100%': '#6149f6'
|
||||
}
|
||||
'100%': '#6149f6',
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
@@ -118,13 +113,13 @@ export default {
|
||||
|
||||
reduce() {
|
||||
this.rate = format(this.rate - 20);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
@import "../../style/var";
|
||||
@import '../../style/var';
|
||||
|
||||
.demo-circle {
|
||||
.van-circle {
|
||||
|
||||
+28
-28
@@ -1,4 +1,4 @@
|
||||
import { createNamespace, isObj, addUnit } from '../utils';
|
||||
import { createNamespace, isObject, addUnit } from '../utils';
|
||||
import { raf, cancelRaf } from '../utils/dom/raf';
|
||||
import { BLUE, WHITE } from '../utils/constant';
|
||||
|
||||
@@ -24,40 +24,40 @@ export default createComponent({
|
||||
strokeLinecap: String,
|
||||
value: {
|
||||
type: Number,
|
||||
default: 0
|
||||
default: 0,
|
||||
},
|
||||
speed: {
|
||||
type: Number,
|
||||
default: 0
|
||||
type: [Number, String],
|
||||
default: 0,
|
||||
},
|
||||
size: {
|
||||
type: [String, Number],
|
||||
default: 100
|
||||
type: [Number, String],
|
||||
default: 100,
|
||||
},
|
||||
fill: {
|
||||
type: String,
|
||||
default: 'none'
|
||||
default: 'none',
|
||||
},
|
||||
rate: {
|
||||
type: Number,
|
||||
default: 100
|
||||
type: [Number, String],
|
||||
default: 100,
|
||||
},
|
||||
layerColor: {
|
||||
type: String,
|
||||
default: WHITE
|
||||
default: WHITE,
|
||||
},
|
||||
color: {
|
||||
type: [String, Object],
|
||||
default: BLUE
|
||||
default: BLUE,
|
||||
},
|
||||
strokeWidth: {
|
||||
type: Number,
|
||||
default: 40
|
||||
type: [Number, String],
|
||||
default: 40,
|
||||
},
|
||||
clockwise: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
|
||||
beforeCreate() {
|
||||
@@ -69,7 +69,7 @@ export default createComponent({
|
||||
const size = addUnit(this.size);
|
||||
return {
|
||||
width: size,
|
||||
height: size
|
||||
height: size,
|
||||
};
|
||||
},
|
||||
|
||||
@@ -78,7 +78,7 @@ export default createComponent({
|
||||
},
|
||||
|
||||
viewBoxSize() {
|
||||
return 1000 + this.strokeWidth;
|
||||
return +this.strokeWidth + 1000;
|
||||
},
|
||||
|
||||
layerStyle() {
|
||||
@@ -86,9 +86,9 @@ export default createComponent({
|
||||
|
||||
return {
|
||||
stroke: `${this.color}`,
|
||||
strokeWidth: `${this.strokeWidth + 1}px`,
|
||||
strokeWidth: `${+this.strokeWidth + 1}px`,
|
||||
strokeLinecap: this.strokeLinecap,
|
||||
strokeDasharray: `${offset}px ${PERIMETER}px`
|
||||
strokeDasharray: `${offset}px ${PERIMETER}px`,
|
||||
};
|
||||
},
|
||||
|
||||
@@ -96,12 +96,12 @@ export default createComponent({
|
||||
return {
|
||||
fill: `${this.fill}`,
|
||||
stroke: `${this.layerColor}`,
|
||||
strokeWidth: `${this.strokeWidth}px`
|
||||
strokeWidth: `${this.strokeWidth}px`,
|
||||
};
|
||||
},
|
||||
|
||||
gradient() {
|
||||
return isObj(this.color);
|
||||
return isObject(this.color);
|
||||
},
|
||||
|
||||
LinearGradient() {
|
||||
@@ -122,15 +122,15 @@ export default createComponent({
|
||||
</linearGradient>
|
||||
</defs>
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
watch: {
|
||||
rate: {
|
||||
handler() {
|
||||
handler(rate) {
|
||||
this.startTime = Date.now();
|
||||
this.startRate = this.value;
|
||||
this.endRate = format(this.rate);
|
||||
this.endRate = format(rate);
|
||||
this.increase = this.endRate > this.startRate;
|
||||
this.duration = Math.abs(
|
||||
((this.startRate - this.endRate) * 1000) / this.speed
|
||||
@@ -143,8 +143,8 @@ export default createComponent({
|
||||
this.$emit('input', this.endRate);
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
@@ -158,7 +158,7 @@ export default createComponent({
|
||||
if (this.increase ? rate < this.endRate : rate > this.endRate) {
|
||||
this.rafId = raf(this.animate);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
render() {
|
||||
@@ -178,5 +178,5 @@ export default createComponent({
|
||||
(this.text && <div class={bem('text')}>{this.text}</div>)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -6,15 +6,15 @@ test('speed is 0', async () => {
|
||||
const wrapper = mount(Circle, {
|
||||
propsData: {
|
||||
rate: 50,
|
||||
value: 0
|
||||
value: 0,
|
||||
},
|
||||
listeners: {
|
||||
input(value) {
|
||||
Vue.nextTick(() => {
|
||||
wrapper.setProps({ value });
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await later();
|
||||
@@ -26,11 +26,11 @@ test('animate', async () => {
|
||||
mount(Circle, {
|
||||
propsData: {
|
||||
rate: 50,
|
||||
speed: 100
|
||||
speed: 100,
|
||||
},
|
||||
listeners: {
|
||||
input: onInput
|
||||
}
|
||||
input: onInput,
|
||||
},
|
||||
});
|
||||
|
||||
await later(50);
|
||||
@@ -41,8 +41,8 @@ test('animate', async () => {
|
||||
test('size prop', () => {
|
||||
const wrapper = mount(Circle, {
|
||||
propsData: {
|
||||
size: 100
|
||||
}
|
||||
size: 100,
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
@@ -51,8 +51,8 @@ test('size prop', () => {
|
||||
test('stroke-linecap prop', () => {
|
||||
const wrapper = mount(Circle, {
|
||||
propsData: {
|
||||
strokeLinecap: 'square'
|
||||
}
|
||||
strokeLinecap: 'square',
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
|
||||
+7
-6
@@ -6,11 +6,12 @@ Quickly and easily create layouts with `van-row` and `van-col`
|
||||
|
||||
### Install
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
import Vue from 'vue';
|
||||
import { Row, Col } from 'vant';
|
||||
import { Col, Row } from 'vant';
|
||||
|
||||
Vue.use(Row).use(Col);
|
||||
Vue.use(Col);
|
||||
Vue.use(Row);
|
||||
```
|
||||
|
||||
## Usage
|
||||
@@ -94,7 +95,7 @@ Setting `type` to `flex` to enable flex layout
|
||||
| Attribute | Description | Type | Default |
|
||||
|------|------|------|------|
|
||||
| type | Layout type, can be set to `flex` | *string* | - |
|
||||
| gutter | Grid spacing(px) | *string \| number* | - |
|
||||
| gutter | Grid spacing(px) | *number \| string* | - |
|
||||
| tag | Custom element tag | *string* | `div` |
|
||||
| justify | Flex main axis,can be set to end/center/space-around/space-between | *string* | `start` |
|
||||
| align | Flex cross axis, be set to center/bottom | *string* | `top` |
|
||||
@@ -103,8 +104,8 @@ Setting `type` to `flex` to enable flex layout
|
||||
|
||||
| Attribute | Description | Type | Default |
|
||||
|------|------|------|------|
|
||||
| span | number of column the grid spans | *string \| number* | - |
|
||||
| offset | number of spacing on the left side of the grid | *string \| number* | - |
|
||||
| span | number of column the grid spans | *number \| string* | - |
|
||||
| offset | number of spacing on the left side of the grid | *number \| string* | - |
|
||||
| tag | Custom element tag | *string* | `div` |
|
||||
|
||||
### Row Events
|
||||
|
||||
@@ -6,11 +6,12 @@ Layout 提供了`van-row`和`van-col`两个组件来进行行列布局
|
||||
|
||||
### 引入
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
import Vue from 'vue';
|
||||
import { Row, Col } from 'vant';
|
||||
import { Col, Row } from 'vant';
|
||||
|
||||
Vue.use(Row).use(Col);
|
||||
Vue.use(Col);
|
||||
Vue.use(Row);
|
||||
```
|
||||
|
||||
## 代码演示
|
||||
@@ -97,7 +98,7 @@ Layout 组件提供了`24列栅格`,通过在`Col`上添加`span`属性设置
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|------|------|------|------|
|
||||
| type | 布局方式,可选值为`flex` | *string* | - |
|
||||
| gutter | 列元素之间的间距(单位为px) | *string \| number* | - |
|
||||
| gutter | 列元素之间的间距(单位为px) | *number \| string* | - |
|
||||
| tag | 自定义元素标签 | *string* | `div` |
|
||||
| justify | Flex 主轴对齐方式,可选值为 `end` `center` <br> `space-around` `space-between` | *string* | `start` |
|
||||
| align | Flex 交叉轴对齐方式,可选值为 `center` `bottom` | *string* | `top` |
|
||||
@@ -106,8 +107,8 @@ Layout 组件提供了`24列栅格`,通过在`Col`上添加`span`属性设置
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|------|------|------|------|
|
||||
| span | 列元素宽度 | *string \| number* | - |
|
||||
| offset | 列元素偏移距离 | *string \| number* | - |
|
||||
| span | 列元素宽度 | *number \| string* | - |
|
||||
| offset | 列元素偏移距离 | *number \| string* | - |
|
||||
| tag | 自定义元素标签 | *string* | `div` |
|
||||
|
||||
### Row Events
|
||||
|
||||
+11
-32
@@ -9,19 +9,13 @@
|
||||
|
||||
<van-row>
|
||||
<van-col span="4">span: 4</van-col>
|
||||
<van-col
|
||||
span="10"
|
||||
offset="4"
|
||||
>
|
||||
<van-col span="10" offset="4">
|
||||
offset: 4, span: 10
|
||||
</van-col>
|
||||
</van-row>
|
||||
|
||||
<van-row>
|
||||
<van-col
|
||||
offset="12"
|
||||
span="12"
|
||||
>
|
||||
<van-col offset="12" span="12">
|
||||
offset: 12, span: 12
|
||||
</van-col>
|
||||
</van-row>
|
||||
@@ -35,47 +29,32 @@
|
||||
</van-row>
|
||||
</demo-block>
|
||||
|
||||
<demo-block
|
||||
v-if="!isWeapp"
|
||||
:title="$t('title3')"
|
||||
>
|
||||
<demo-block v-if="!isWeapp" :title="$t('title3')">
|
||||
<van-row type="flex">
|
||||
<van-col span="6">span: 6</van-col>
|
||||
<van-col span="6">span: 6</van-col>
|
||||
<van-col span="6">span: 6</van-col>
|
||||
</van-row>
|
||||
|
||||
<van-row
|
||||
type="flex"
|
||||
justify="center"
|
||||
>
|
||||
<van-row type="flex" justify="center">
|
||||
<van-col span="6">span: 6</van-col>
|
||||
<van-col span="6">span: 6</van-col>
|
||||
<van-col span="6">span: 6</van-col>
|
||||
</van-row>
|
||||
|
||||
<van-row
|
||||
type="flex"
|
||||
justify="end"
|
||||
>
|
||||
<van-row type="flex" justify="end">
|
||||
<van-col span="6">span: 6</van-col>
|
||||
<van-col span="6">span: 6</van-col>
|
||||
<van-col span="6">span: 6</van-col>
|
||||
</van-row>
|
||||
|
||||
<van-row
|
||||
type="flex"
|
||||
justify="space-between"
|
||||
>
|
||||
<van-row type="flex" justify="space-between">
|
||||
<van-col span="6">span: 6</van-col>
|
||||
<van-col span="6">span: 6</van-col>
|
||||
<van-col span="6">span: 6</van-col>
|
||||
</van-row>
|
||||
|
||||
<van-row
|
||||
type="flex"
|
||||
justify="space-around"
|
||||
>
|
||||
<van-row type="flex" justify="space-around">
|
||||
<van-col span="6">span: 6</van-col>
|
||||
<van-col span="6">span: 6</van-col>
|
||||
<van-col span="6">span: 6</van-col>
|
||||
@@ -89,13 +68,13 @@ export default {
|
||||
i18n: {
|
||||
'zh-CN': {
|
||||
title2: '在列元素之间增加间距',
|
||||
title3: 'Flex 布局'
|
||||
title3: 'Flex 布局',
|
||||
},
|
||||
'en-US': {
|
||||
title2: 'Column Spacing',
|
||||
title3: 'Flex Layout'
|
||||
}
|
||||
}
|
||||
title3: 'Flex Layout',
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
+5
-5
@@ -8,8 +8,8 @@ export default createComponent({
|
||||
offset: [Number, String],
|
||||
tag: {
|
||||
type: String,
|
||||
default: 'div'
|
||||
}
|
||||
default: 'div',
|
||||
},
|
||||
},
|
||||
|
||||
computed: {
|
||||
@@ -20,13 +20,13 @@ export default createComponent({
|
||||
style() {
|
||||
const padding = `${this.gutter / 2}px`;
|
||||
return this.gutter ? { paddingLeft: padding, paddingRight: padding } : {};
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
onClick(event) {
|
||||
this.$emit('click', event);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
render() {
|
||||
@@ -40,5 +40,5 @@ export default createComponent({
|
||||
{this.slots()}
|
||||
</this.tag>
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
+8
-2
@@ -8,7 +8,13 @@
|
||||
|
||||
.generate-col(24);
|
||||
.generate-col(@n, @i: 1) when (@i =< @n) {
|
||||
.van-col--@{i} { width: @i * 100% / 24; }
|
||||
.van-col--offset-@{i} { margin-left: @i * 100% / 24; }
|
||||
.van-col--@{i} {
|
||||
width: @i * 100% / 24;
|
||||
}
|
||||
|
||||
.van-col--offset-@{i} {
|
||||
margin-left: @i * 100% / 24;
|
||||
}
|
||||
|
||||
.generate-col(@n, (@i + 1));
|
||||
}
|
||||
|
||||
+16
-10
@@ -1,9 +1,14 @@
|
||||
// Utils
|
||||
import { createNamespace, isDef } from '../utils';
|
||||
import { BORDER_TOP } from '../utils/constant';
|
||||
import { raf, doubleRaf } from '../utils/dom/raf';
|
||||
|
||||
// Mixins
|
||||
import { ChildrenMixin } from '../mixins/relation';
|
||||
|
||||
// Components
|
||||
import Cell from '../cell';
|
||||
import { cellProps } from '../cell/shared';
|
||||
import { ChildrenMixin } from '../mixins/relation';
|
||||
|
||||
const [createComponent, bem] = createNamespace('collapse-item');
|
||||
|
||||
@@ -18,14 +23,14 @@ export default createComponent({
|
||||
disabled: Boolean,
|
||||
isLink: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
show: null,
|
||||
inited: null
|
||||
inited: null,
|
||||
};
|
||||
},
|
||||
|
||||
@@ -53,7 +58,7 @@ export default createComponent({
|
||||
return accordion
|
||||
? value === this.currentName
|
||||
: value.some(name => name === this.currentName);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
created() {
|
||||
@@ -96,7 +101,7 @@ export default createComponent({
|
||||
this.onTransitionEnd();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
@@ -106,9 +111,10 @@ export default createComponent({
|
||||
}
|
||||
|
||||
const { parent, currentName } = this;
|
||||
const name = parent.accordion && currentName === parent.value ? '' : currentName;
|
||||
const close = parent.accordion && currentName === parent.value;
|
||||
const name = close ? '' : currentName;
|
||||
|
||||
this.parent.switch(name, !this.expanded);
|
||||
parent.switch(name, !this.expanded);
|
||||
},
|
||||
|
||||
onTransitionEnd() {
|
||||
@@ -162,7 +168,7 @@ export default createComponent({
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
render() {
|
||||
@@ -172,5 +178,5 @@ export default createComponent({
|
||||
{this.genContent()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
+11
-14
@@ -2,11 +2,12 @@
|
||||
|
||||
### Install
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
import Vue from 'vue';
|
||||
import { Collapse, CollapseItem } from 'vant';
|
||||
|
||||
Vue.use(Collapse).use(CollapseItem);
|
||||
Vue.use(Collapse);
|
||||
Vue.use(CollapseItem);
|
||||
```
|
||||
|
||||
## Usage
|
||||
@@ -23,7 +24,7 @@ Use `v-model` to control the name of active panels
|
||||
</van-collapse>
|
||||
```
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
@@ -45,7 +46,7 @@ In accordion mode, only one panel can be expanded at the same time.
|
||||
</van-collapse>
|
||||
```
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
@@ -63,17 +64,13 @@ export default {
|
||||
<div slot="title">Title1 <van-icon name="question-o" /></div>
|
||||
Content
|
||||
</van-collapse-item>
|
||||
<van-collapse-item
|
||||
title="Title2"
|
||||
name="2"
|
||||
icon="shop-o"
|
||||
>
|
||||
<van-collapse-item title="Title2" name="2" icon="shop-o">
|
||||
Content
|
||||
</van-collapse-item>
|
||||
</van-collapse>
|
||||
```
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
@@ -89,7 +86,7 @@ export default {
|
||||
|
||||
| Attribute | Description | Type | Default |
|
||||
|------|------|------|------|
|
||||
| v-model | Names of current active panels | accordion mode: *string \| number*<br>non-accordion mode:*(string \| number)[]* | - |
|
||||
| v-model | Names of current active panels | accordion mode: *number \| string*<br>non-accordion mode:*(number \| string)[]* | - |
|
||||
| accordion | Whether to be accordion mode | *boolean* | `false` |
|
||||
| border | Whether to show outer border | *boolean* | `true` |
|
||||
|
||||
@@ -103,11 +100,11 @@ export default {
|
||||
|
||||
| Attribute | Description | Type | Default |
|
||||
|------|------|------|------|
|
||||
| name | Name | *string \| number* | `index` |
|
||||
| name | Name | *number \| string* | `index` |
|
||||
| icon | Left Icon | *string* | - |
|
||||
| size | Title size,can be set to `large` | *string* | - |
|
||||
| title | Title | *string \| number* | - |
|
||||
| value | Right text | *string \| number* | - |
|
||||
| title | Title | *number \| string* | - |
|
||||
| value | Right text | *number \| string* | - |
|
||||
| label | Description below the title | *string* | - |
|
||||
| border | Whether to show inner border | *boolean* | `true` |
|
||||
| disabled | Whether to disabled collapse | *boolean* | `false` |
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
|
||||
### 引入
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
import Vue from 'vue';
|
||||
import { Collapse, CollapseItem } from 'vant';
|
||||
|
||||
Vue.use(Collapse).use(CollapseItem);
|
||||
Vue.use(Collapse);
|
||||
Vue.use(CollapseItem);
|
||||
```
|
||||
|
||||
## 代码演示
|
||||
@@ -23,7 +24,7 @@ Vue.use(Collapse).use(CollapseItem);
|
||||
</van-collapse>
|
||||
```
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
@@ -45,7 +46,7 @@ export default {
|
||||
</van-collapse>
|
||||
```
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
@@ -63,18 +64,13 @@ export default {
|
||||
<div slot="title">标题1 <van-icon name="question-o" /></div>
|
||||
内容
|
||||
</van-collapse-item>
|
||||
|
||||
<van-collapse-item
|
||||
title="标题2"
|
||||
name="2"
|
||||
icon="shop-o"
|
||||
>
|
||||
<van-collapse-item title="标题2" name="2" icon="shop-o">
|
||||
内容
|
||||
</van-collapse-item>
|
||||
</van-collapse>
|
||||
```
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
@@ -90,7 +86,7 @@ export default {
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|------|------|------|------|
|
||||
| v-model | 当前展开面板的 name | 手风琴模式:*string \| number*<br>非手风琴模式:*(string \| number)[]* | - |
|
||||
| v-model | 当前展开面板的 name | 手风琴模式:*number \| string*<br>非手风琴模式:*(number \| string)[]* | - |
|
||||
| accordion | 是否开启手风琴模式 | *boolean* | `false` |
|
||||
| border | 是否显示外边框 | *boolean* | `true` |
|
||||
|
||||
@@ -104,12 +100,12 @@ export default {
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|------|------|------|------|
|
||||
| name | 唯一标识符,默认为索引值 | *string \| number* | `index` |
|
||||
| icon | 标题栏左侧图标名称或图片链接,可选值见 [Icon 组件](#/zh-CN/icon) | *string* | - |
|
||||
| name | 唯一标识符,默认为索引值 | *number \| string* | `index` |
|
||||
| icon | 标题栏左侧 [图标名称](#/zh-CN/icon) 或图片链接 | *string* | - |
|
||||
| size | 标题栏大小,可选值为 `large` | *string* | - |
|
||||
| title | 标题栏左侧内容 | *string \| number* | - |
|
||||
| value | 标题栏右侧内容 | *string \| number* | - |
|
||||
| label | 标题栏描述信息 | *string \| number* | - |
|
||||
| title | 标题栏左侧内容 | *number \| string* | - |
|
||||
| value | 标题栏右侧内容 | *number \| string* | - |
|
||||
| label | 标题栏描述信息 | *number \| string* | - |
|
||||
| border | 是否显示内边框 | *boolean* | `true` |
|
||||
| is-link | 是否展示标题栏右侧箭头并开启点击反馈 | *boolean* | `true` |
|
||||
| disabled | 是否禁用面板 | *boolean* | `false` |
|
||||
|
||||
+22
-18
@@ -2,25 +2,29 @@
|
||||
<demo-section>
|
||||
<demo-block :title="$t('basicUsage')">
|
||||
<van-collapse v-model="active1">
|
||||
<van-collapse-item :title="$t('title') + 1">{{ $t('text') }}</van-collapse-item>
|
||||
<van-collapse-item :title="$t('title') + 2">{{ $t('text') }}</van-collapse-item>
|
||||
<van-collapse-item
|
||||
:title="$t('title') + 3"
|
||||
disabled
|
||||
>
|
||||
<van-collapse-item :title="$t('title') + 1">
|
||||
{{ $t('text') }}
|
||||
</van-collapse-item>
|
||||
<van-collapse-item :title="$t('title') + 2">
|
||||
{{ $t('text') }}
|
||||
</van-collapse-item>
|
||||
<van-collapse-item :title="$t('title') + 3" disabled>
|
||||
{{ $t('text') }}
|
||||
</van-collapse-item>
|
||||
</van-collapse>
|
||||
</demo-block>
|
||||
|
||||
<demo-block :title="$t('accordion')">
|
||||
<van-collapse
|
||||
v-model="active2"
|
||||
accordion
|
||||
>
|
||||
<van-collapse-item :title="$t('title') + 1">{{ $t('text') }}</van-collapse-item>
|
||||
<van-collapse-item :title="$t('title') + 2">{{ $t('text') }}</van-collapse-item>
|
||||
<van-collapse-item :title="$t('title') + 3">{{ $t('text') }}</van-collapse-item>
|
||||
<van-collapse v-model="active2" accordion>
|
||||
<van-collapse-item :title="$t('title') + 1">
|
||||
{{ $t('text') }}
|
||||
</van-collapse-item>
|
||||
<van-collapse-item :title="$t('title') + 2">
|
||||
{{ $t('text') }}
|
||||
</van-collapse-item>
|
||||
<van-collapse-item :title="$t('title') + 3">
|
||||
{{ $t('text') }}
|
||||
</van-collapse-item>
|
||||
</van-collapse>
|
||||
</demo-block>
|
||||
|
||||
@@ -50,22 +54,22 @@ export default {
|
||||
'zh-CN': {
|
||||
accordion: '手风琴',
|
||||
titleSlot: '自定义标题内容',
|
||||
text: '代码是写出来给人看的,附带能在机器上运行'
|
||||
text: '代码是写出来给人看的,附带能在机器上运行',
|
||||
},
|
||||
'en-US': {
|
||||
accordion: 'Accordion',
|
||||
titleSlot: 'Custom title',
|
||||
text: 'Content'
|
||||
}
|
||||
text: 'Content',
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
active1: [0],
|
||||
active2: 0,
|
||||
active3: []
|
||||
active3: [],
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
@@ -12,8 +12,8 @@ export default createComponent({
|
||||
value: [String, Number, Array],
|
||||
border: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
@@ -25,7 +25,7 @@ export default createComponent({
|
||||
}
|
||||
this.$emit('change', name);
|
||||
this.$emit('input', name);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
render() {
|
||||
@@ -34,5 +34,5 @@ export default createComponent({
|
||||
{this.slots()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -10,7 +10,9 @@ exports[`renders demo correctly 1`] = `
|
||||
<!----></i>
|
||||
</div>
|
||||
<div class="van-collapse-item__wrapper">
|
||||
<div class="van-collapse-item__content">代码是写出来给人看的,附带能在机器上运行</div>
|
||||
<div class="van-collapse-item__content">
|
||||
代码是写出来给人看的,附带能在机器上运行
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="van-collapse-item van-hairline--top">
|
||||
@@ -35,7 +37,9 @@ exports[`renders demo correctly 1`] = `
|
||||
<!----></i>
|
||||
</div>
|
||||
<div class="van-collapse-item__wrapper">
|
||||
<div class="van-collapse-item__content">代码是写出来给人看的,附带能在机器上运行</div>
|
||||
<div class="van-collapse-item__content">
|
||||
代码是写出来给人看的,附带能在机器上运行
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="van-collapse-item van-hairline--top">
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
import Vue from 'vue';
|
||||
import Collapse from '..';
|
||||
import CollapseItem from '../../collapse-item';
|
||||
import { later, mount } from '../../../test';
|
||||
|
||||
Vue.use(Collapse);
|
||||
Vue.use(CollapseItem);
|
||||
|
||||
const component = {
|
||||
template: `
|
||||
<van-collapse v-model="active" :accordion="accordion" :border="border">
|
||||
@@ -18,14 +14,14 @@ const component = {
|
||||
accordion: Boolean,
|
||||
border: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
active: this.accordion ? '' : []
|
||||
active: this.accordion ? '' : [],
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
test('basic mode', async () => {
|
||||
@@ -49,8 +45,8 @@ test('basic mode', async () => {
|
||||
test('accordion', async () => {
|
||||
const wrapper = mount(component, {
|
||||
propsData: {
|
||||
accordion: true
|
||||
}
|
||||
accordion: true,
|
||||
},
|
||||
});
|
||||
|
||||
const titles = wrapper.findAll('.van-collapse-item__title');
|
||||
@@ -82,9 +78,9 @@ test('render collapse-item slot', () => {
|
||||
`,
|
||||
data() {
|
||||
return {
|
||||
active: []
|
||||
active: [],
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
@@ -93,8 +89,8 @@ test('render collapse-item slot', () => {
|
||||
test('disable border', () => {
|
||||
const wrapper = mount(component, {
|
||||
propsData: {
|
||||
border: false
|
||||
}
|
||||
border: false,
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
@@ -110,14 +106,14 @@ test('lazy render collapse content', async () => {
|
||||
`,
|
||||
components: {
|
||||
Collapse,
|
||||
CollapseItem
|
||||
CollapseItem,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
content: '',
|
||||
active: []
|
||||
active: [],
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const titles = wrapper.findAll('.van-collapse-item__title');
|
||||
@@ -140,9 +136,9 @@ test('warn when value type is incorrect', () => {
|
||||
`,
|
||||
data() {
|
||||
return {
|
||||
active: 0
|
||||
active: 0,
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
expect(error).toHaveBeenCalledTimes(1);
|
||||
|
||||
@@ -2,14 +2,13 @@
|
||||
|
||||
### Install
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
import Vue from 'vue';
|
||||
import { ContactCard, ContactList, ContactEdit } from 'vant';
|
||||
|
||||
Vue
|
||||
.use(ContactCard)
|
||||
.use(ContactList)
|
||||
.use(ContactEdit);
|
||||
Vue.use(ContactCard);
|
||||
Vue.use(ContactList);
|
||||
Vue.use(ContactEdit);
|
||||
```
|
||||
|
||||
## Usage
|
||||
@@ -47,7 +46,7 @@ Vue
|
||||
</van-popup>
|
||||
```
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
@@ -152,7 +151,7 @@ export default {
|
||||
|
||||
| Attribute | Description | Type | Default |
|
||||
|------|------|------|------|
|
||||
| v-model | Id of chosen contact | *string \| number* | - |
|
||||
| v-model | Id of chosen contact | *number \| string* | - |
|
||||
| list | Contact list | *Contact[]* | `[]` |
|
||||
| add-text | Add button text | *string* | `Add new contact` |
|
||||
| default-tag-text `v2.3.0` | Default tag text | *string* | - |
|
||||
@@ -189,7 +188,7 @@ export default {
|
||||
|
||||
| key | Description | Type |
|
||||
|------|------|------|
|
||||
| id | ID | *string \| number* |
|
||||
| id | ID | *number \| string* |
|
||||
| name | Name | *string* |
|
||||
| tel | Phone | *string* |
|
||||
| isDefault | Is default contact | *boolean* |
|
||||
|
||||
@@ -6,14 +6,13 @@
|
||||
|
||||
### 引入
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
import Vue from 'vue';
|
||||
import { ContactCard, ContactList, ContactEdit } from 'vant';
|
||||
|
||||
Vue
|
||||
.use(ContactCard)
|
||||
.use(ContactList)
|
||||
.use(ContactEdit);
|
||||
Vue.use(ContactCard);
|
||||
Vue.use(ContactList);
|
||||
Vue.use(ContactEdit);
|
||||
```
|
||||
|
||||
## 代码演示
|
||||
@@ -51,7 +50,7 @@ Vue
|
||||
</van-popup>
|
||||
```
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
@@ -156,7 +155,7 @@ export default {
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|------|------|------|------|
|
||||
| v-model | 当前选中联系人的 id | *string \| number* | - |
|
||||
| v-model | 当前选中联系人的 id | *number \| string* | - |
|
||||
| list | 联系人列表 | *Contact[]* | `[]` |
|
||||
| add-text | 新建按钮文案 | *string* | `新建联系人` |
|
||||
| default-tag-text `v2.3.0` | 默认联系人标签文案 | *string* | - |
|
||||
@@ -192,7 +191,7 @@ export default {
|
||||
|
||||
| 键名 | 说明 | 类型 |
|
||||
|------|------|------|
|
||||
| id | 每位联系人的唯一标识 | *string \| number* |
|
||||
| id | 每位联系人的唯一标识 | *number \| string* |
|
||||
| name | 联系人姓名 | *string* |
|
||||
| tel | 联系人手机号 | *string \| number* |
|
||||
| tel | 联系人手机号 | *number \| string* |
|
||||
| isDefault | 是否为默认联系人 | *boolean* |
|
||||
|
||||
@@ -8,11 +8,7 @@
|
||||
@click="showList = true"
|
||||
/>
|
||||
|
||||
<van-popup
|
||||
v-model="showList"
|
||||
position="bottom"
|
||||
:lazy-render="false"
|
||||
>
|
||||
<van-popup v-model="showList" position="bottom" :lazy-render="false">
|
||||
<van-contact-list
|
||||
v-model="chosenContactId"
|
||||
:list="list"
|
||||
@@ -23,11 +19,7 @@
|
||||
/>
|
||||
</van-popup>
|
||||
|
||||
<van-popup
|
||||
v-model="showEdit"
|
||||
position="bottom"
|
||||
:lazy-render="false"
|
||||
>
|
||||
<van-popup v-model="showEdit" position="bottom" :lazy-render="false">
|
||||
<van-contact-edit
|
||||
show-set-default
|
||||
:set-default-label="$t('defaultLabel')"
|
||||
@@ -56,13 +48,13 @@ export default {
|
||||
'zh-CN': {
|
||||
name: '张三',
|
||||
defaultLabel: '设为默认联系人',
|
||||
defaultTagText: '默认'
|
||||
defaultTagText: '默认',
|
||||
},
|
||||
'en-US': {
|
||||
name: 'John Snow',
|
||||
defaultLabel: 'Set as the default contact',
|
||||
defaultTagText: 'default'
|
||||
}
|
||||
defaultTagText: 'default',
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
@@ -72,7 +64,7 @@ export default {
|
||||
showList: false,
|
||||
showEdit: false,
|
||||
isEdit: false,
|
||||
list: []
|
||||
list: [],
|
||||
};
|
||||
},
|
||||
|
||||
@@ -82,7 +74,7 @@ export default {
|
||||
name: this.$t('name'),
|
||||
tel: '13000000000',
|
||||
id: 0,
|
||||
isDefault: 1
|
||||
isDefault: 1,
|
||||
};
|
||||
},
|
||||
|
||||
@@ -93,7 +85,7 @@ export default {
|
||||
currentContact() {
|
||||
const id = this.chosenContactId;
|
||||
return id !== null ? this.list.filter(item => item.id === id)[0] : {};
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
created() {
|
||||
@@ -135,8 +127,8 @@ export default {
|
||||
if (this.chosenContactId === info.id) {
|
||||
this.chosenContactId = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
// Utils
|
||||
import { createNamespace } from '../utils';
|
||||
import { emit, inherit } from '../utils/functional';
|
||||
|
||||
// Components
|
||||
import Cell from '../cell';
|
||||
|
||||
// Types
|
||||
@@ -37,7 +40,7 @@ function ContactCard(
|
||||
|
||||
return [
|
||||
<div>{`${t('name')}:${props.name}`}</div>,
|
||||
<div>{`${t('tel')}:${props.tel}`}</div>
|
||||
<div>{`${t('tel')}:${props.tel}`}</div>,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -63,12 +66,12 @@ ContactCard.props = {
|
||||
addText: String,
|
||||
editable: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
default: true,
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'add'
|
||||
}
|
||||
default: 'add',
|
||||
},
|
||||
};
|
||||
|
||||
export default createComponent<ContactCardProps>(ContactCard);
|
||||
|
||||
@@ -5,7 +5,7 @@ import { mount, later } from '../../../test';
|
||||
|
||||
const contactInfo = {
|
||||
name: 'test',
|
||||
tel: '123123213'
|
||||
tel: '123123213',
|
||||
};
|
||||
|
||||
describe('ContactCard', () => {
|
||||
@@ -14,9 +14,9 @@ describe('ContactCard', () => {
|
||||
const wrapper = mount(ContactCard, {
|
||||
context: {
|
||||
on: {
|
||||
click
|
||||
}
|
||||
}
|
||||
click,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
wrapper.trigger('click');
|
||||
@@ -27,13 +27,13 @@ describe('ContactCard', () => {
|
||||
const click = jest.fn();
|
||||
const wrapper = mount(ContactCard, {
|
||||
propsData: {
|
||||
editable: false
|
||||
editable: false,
|
||||
},
|
||||
context: {
|
||||
on: {
|
||||
click
|
||||
}
|
||||
}
|
||||
click,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
wrapper.trigger('click');
|
||||
@@ -45,8 +45,8 @@ describe('ContactList', () => {
|
||||
test('render', () => {
|
||||
const wrapper = mount(ContactList, {
|
||||
propsData: {
|
||||
list: [contactInfo]
|
||||
}
|
||||
list: [contactInfo],
|
||||
},
|
||||
});
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
@@ -55,13 +55,13 @@ describe('ContactList', () => {
|
||||
const onSelect = jest.fn();
|
||||
const wrapper = mount(ContactList, {
|
||||
propsData: {
|
||||
list: [contactInfo]
|
||||
list: [contactInfo],
|
||||
},
|
||||
context: {
|
||||
on: {
|
||||
select: onSelect
|
||||
}
|
||||
}
|
||||
select: onSelect,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
wrapper.find('.van-radio__icon').trigger('click');
|
||||
@@ -74,8 +74,8 @@ describe('ContactEdit', () => {
|
||||
const createComponent = () => {
|
||||
const wrapper = mount(ContactEdit, {
|
||||
propsData: {
|
||||
contactInfo
|
||||
}
|
||||
contactInfo,
|
||||
},
|
||||
});
|
||||
|
||||
const button = wrapper.find('.van-button');
|
||||
@@ -86,7 +86,7 @@ describe('ContactEdit', () => {
|
||||
data,
|
||||
field,
|
||||
button,
|
||||
errorInfo
|
||||
errorInfo,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -114,7 +114,7 @@ describe('ContactEdit', () => {
|
||||
expect(errorInfo.tel).toBeFalsy();
|
||||
expect(wrapper.emitted('save')[0][0]).toEqual({
|
||||
name: 'test',
|
||||
tel: '13000000000'
|
||||
tel: '13000000000',
|
||||
});
|
||||
});
|
||||
|
||||
@@ -127,8 +127,8 @@ describe('ContactEdit', () => {
|
||||
test('delete contact', async () => {
|
||||
const wrapper = mount(ContactEdit, {
|
||||
propsData: {
|
||||
isEdit: true
|
||||
}
|
||||
isEdit: true,
|
||||
},
|
||||
});
|
||||
|
||||
const deleteButton = wrapper.findAll('.van-button').at(1);
|
||||
|
||||
+18
-15
@@ -1,16 +1,19 @@
|
||||
// Utils
|
||||
import { createNamespace } from '../utils';
|
||||
import Button from '../button';
|
||||
import { isMobile } from '../utils/validate/mobile';
|
||||
|
||||
// Components
|
||||
import Cell from '../cell';
|
||||
import Field from '../field';
|
||||
import Button from '../button';
|
||||
import Dialog from '../dialog';
|
||||
import Switch from '../switch';
|
||||
import Cell from '../cell';
|
||||
import { isMobile } from '../utils/validate/mobile';
|
||||
|
||||
const [createComponent, bem, t] = createNamespace('contact-edit');
|
||||
|
||||
const defaultContact = {
|
||||
tel: '',
|
||||
name: ''
|
||||
name: '',
|
||||
};
|
||||
|
||||
export default createComponent({
|
||||
@@ -22,24 +25,24 @@ export default createComponent({
|
||||
setDefaultLabel: String,
|
||||
contactInfo: {
|
||||
type: Object,
|
||||
default: () => ({ ...defaultContact })
|
||||
default: () => ({ ...defaultContact }),
|
||||
},
|
||||
telValidator: {
|
||||
type: Function,
|
||||
default: isMobile
|
||||
}
|
||||
default: isMobile,
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
data: {
|
||||
...defaultContact,
|
||||
...this.contactInfo
|
||||
...this.contactInfo,
|
||||
},
|
||||
errorInfo: {
|
||||
name: '',
|
||||
tel: ''
|
||||
}
|
||||
tel: '',
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
@@ -47,9 +50,9 @@ export default createComponent({
|
||||
contactInfo(val) {
|
||||
this.data = {
|
||||
...defaultContact,
|
||||
...val
|
||||
...val,
|
||||
};
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
@@ -83,11 +86,11 @@ export default createComponent({
|
||||
|
||||
onDelete() {
|
||||
Dialog.confirm({
|
||||
message: t('confirmDelete')
|
||||
message: t('confirmDelete'),
|
||||
}).then(() => {
|
||||
this.$emit('delete', this.data);
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
render() {
|
||||
@@ -152,5 +155,5 @@ export default createComponent({
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
// Utils
|
||||
import { createNamespace } from '../utils';
|
||||
import { RED } from '../utils/constant';
|
||||
import { emit, inherit } from '../utils/functional';
|
||||
|
||||
// Components
|
||||
import Tag from '../tag';
|
||||
import Icon from '../icon';
|
||||
import Cell from '../cell';
|
||||
import Tag from '../tag';
|
||||
import Button from '../button';
|
||||
import Radio from '../radio';
|
||||
import Button from '../button';
|
||||
import RadioGroup from '../radio-group';
|
||||
|
||||
// Types
|
||||
import { CreateElement, RenderContext, VNode } from 'vue/types';
|
||||
import { DefaultSlots } from '../utils/types';
|
||||
import { CreateElement, RenderContext, VNode } from 'vue/types';
|
||||
|
||||
export type ContactListItem = {
|
||||
id: string | number;
|
||||
@@ -122,7 +125,7 @@ ContactList.props = {
|
||||
value: null as any,
|
||||
list: Array,
|
||||
addText: String,
|
||||
defaultTagText: String
|
||||
defaultTagText: String,
|
||||
};
|
||||
|
||||
export default createComponent(ContactList);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
### Install
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
import Vue from 'vue';
|
||||
import { CountDown } from 'vant';
|
||||
|
||||
@@ -30,20 +30,13 @@ export default {
|
||||
### Custom Format
|
||||
|
||||
```html
|
||||
<van-count-down
|
||||
:time="time"
|
||||
format="DD Day, HH:mm:ss"
|
||||
/>
|
||||
<van-count-down :time="time" format="DD Day, HH:mm:ss" />
|
||||
```
|
||||
|
||||
### Millisecond
|
||||
|
||||
```html
|
||||
<van-count-down
|
||||
millisecond
|
||||
:time="time"
|
||||
format="HH:mm:ss:SS"
|
||||
/>
|
||||
<van-count-down millisecond :time="time" format="HH:mm:ss:SS" />
|
||||
```
|
||||
|
||||
### Custom Style
|
||||
@@ -89,6 +82,8 @@ export default {
|
||||
```
|
||||
|
||||
```js
|
||||
import { Toast } from 'vant';
|
||||
|
||||
export default {
|
||||
methods: {
|
||||
start() {
|
||||
@@ -101,7 +96,7 @@ export default {
|
||||
this.$refs.countDown.reset();
|
||||
},
|
||||
finish() {
|
||||
this.$toast('Finished');
|
||||
Toast('Finished');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -113,7 +108,7 @@ export default {
|
||||
|
||||
| Attribute | Description | Type | Default |
|
||||
|------|------|------|------|
|
||||
| time | Total time | *number* | - |
|
||||
| time | Total time | *number \| string* | `0` |
|
||||
| format | Time format | *string* | `HH:mm:ss` |
|
||||
| auto-start | Whether to auto start count down | *boolean* | `true` |
|
||||
| millisecond | Whether to enable millisecond render | *boolean* | `false` |
|
||||
@@ -135,6 +130,7 @@ export default {
|
||||
| Event | Description | Arguments |
|
||||
|------|------|------|
|
||||
| finish | Triggered when count down finished | - |
|
||||
| change `v2.4.4` | Triggered when count down changed | timeData |
|
||||
|
||||
### Slots
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
### 引入
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
import Vue from 'vue';
|
||||
import { CountDown } from 'vant';
|
||||
|
||||
@@ -34,10 +34,7 @@ export default {
|
||||
通过`format`属性设置倒计时文本的内容
|
||||
|
||||
```html
|
||||
<van-count-down
|
||||
:time="time"
|
||||
format="DD 天 HH 时 mm 分 ss 秒"
|
||||
/>
|
||||
<van-count-down :time="time" format="DD 天 HH 时 mm 分 ss 秒" />
|
||||
```
|
||||
|
||||
### 毫秒级渲染
|
||||
@@ -45,11 +42,7 @@ export default {
|
||||
倒计时默认每秒渲染一次,设置`millisecond`属性可以开启毫秒级渲染
|
||||
|
||||
```html
|
||||
<van-count-down
|
||||
millisecond
|
||||
:time="time"
|
||||
format="HH:mm:ss:SS"
|
||||
/>
|
||||
<van-count-down millisecond :time="time" format="HH:mm:ss:SS" />
|
||||
```
|
||||
|
||||
### 自定义样式
|
||||
@@ -99,6 +92,8 @@ export default {
|
||||
```
|
||||
|
||||
```js
|
||||
import { Toast } from 'vant';
|
||||
|
||||
export default {
|
||||
methods: {
|
||||
start() {
|
||||
@@ -111,7 +106,7 @@ export default {
|
||||
this.$refs.countDown.reset();
|
||||
},
|
||||
finish() {
|
||||
this.$toast('倒计时结束');
|
||||
Toast('倒计时结束');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -123,7 +118,7 @@ export default {
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|------|------|------|------|
|
||||
| time | 倒计时时长,单位毫秒 | *number* | - |
|
||||
| time | 倒计时时长,单位毫秒 | *number \| string* | `0` |
|
||||
| format | 时间格式 | *string* | `HH:mm:ss` |
|
||||
| auto-start | 是否自动开始倒计时 | *boolean* | `true` |
|
||||
| millisecond | 是否开启毫秒级渲染 | *boolean* | `false` |
|
||||
@@ -145,6 +140,7 @@ export default {
|
||||
| 事件名 | 说明 | 回调参数 |
|
||||
|------|------|------|
|
||||
| finish | 倒计时结束时触发 | - |
|
||||
| change `v2.4.4` | 倒计时变化时触发 | timeData |
|
||||
|
||||
### Slots
|
||||
|
||||
@@ -164,7 +160,7 @@ export default {
|
||||
|
||||
### 方法
|
||||
|
||||
通过 [ref](https://cn.vuejs.org/v2/api/#ref) 可以获取到 CountDown 实例并调用实例方法
|
||||
通过 ref 可以获取到 CountDown 实例并调用实例方法,详见 [组件实例方法](#/zh-CN/quickstart#zu-jian-shi-li-fang-fa)
|
||||
|
||||
| 方法名 | 说明 | 参数 | 返回值 |
|
||||
|------|------|------|------|
|
||||
|
||||
@@ -60,7 +60,7 @@ export default {
|
||||
reset: '重置',
|
||||
pause: '暂停',
|
||||
start: '开始',
|
||||
finished: '倒计时结束'
|
||||
finished: '倒计时结束',
|
||||
},
|
||||
'en-US': {
|
||||
millisecond: 'Millisecond',
|
||||
@@ -71,13 +71,13 @@ export default {
|
||||
reset: 'Reset',
|
||||
pause: 'Pause',
|
||||
start: 'Start',
|
||||
finished: 'Finished'
|
||||
}
|
||||
finished: 'Finished',
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
time: 30 * 60 * 60 * 1000
|
||||
time: 30 * 60 * 60 * 1000,
|
||||
};
|
||||
},
|
||||
|
||||
@@ -92,8 +92,8 @@ export default {
|
||||
|
||||
reset() {
|
||||
this.$refs.countDown.reset();
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
+13
-12
@@ -8,22 +8,22 @@ export default createComponent({
|
||||
props: {
|
||||
millisecond: Boolean,
|
||||
time: {
|
||||
type: Number,
|
||||
default: 0
|
||||
type: [Number, String],
|
||||
default: 0,
|
||||
},
|
||||
format: {
|
||||
type: String,
|
||||
default: 'HH:mm:ss'
|
||||
default: 'HH:mm:ss',
|
||||
},
|
||||
autoStart: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
remain: 0
|
||||
remain: 0,
|
||||
};
|
||||
},
|
||||
|
||||
@@ -34,14 +34,14 @@ export default createComponent({
|
||||
|
||||
formattedTime() {
|
||||
return parseFormat(this.format, this.timeData);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
watch: {
|
||||
time: {
|
||||
immediate: true,
|
||||
handler: 'reset'
|
||||
}
|
||||
handler: 'reset',
|
||||
},
|
||||
},
|
||||
|
||||
activated() {
|
||||
@@ -84,7 +84,7 @@ export default createComponent({
|
||||
// @exposed-api
|
||||
reset() {
|
||||
this.pause();
|
||||
this.remain = this.time;
|
||||
this.remain = +this.time;
|
||||
|
||||
if (this.autoStart) {
|
||||
this.start();
|
||||
@@ -141,12 +141,13 @@ export default createComponent({
|
||||
|
||||
setRemain(remain) {
|
||||
this.remain = remain;
|
||||
this.$emit('change', this.timeData);
|
||||
|
||||
if (remain === 0) {
|
||||
this.pause();
|
||||
this.$emit('finish');
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
render() {
|
||||
@@ -155,5 +156,5 @@ export default createComponent({
|
||||
{this.slots('default', this.timeData) || this.formattedTime}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
import Vue from 'vue';
|
||||
import CountDown from '..';
|
||||
import { mount, later } from '../../../test';
|
||||
|
||||
Vue.use(CountDown);
|
||||
|
||||
test('macro task finish event', async () => {
|
||||
const wrapper = mount(CountDown, {
|
||||
propsData: {
|
||||
time: 1
|
||||
}
|
||||
time: 1,
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper.emitted('finish')).toBeFalsy();
|
||||
@@ -20,8 +17,8 @@ test('micro task finish event', async () => {
|
||||
const wrapper = mount(CountDown, {
|
||||
propsData: {
|
||||
time: 1,
|
||||
millisecond: true
|
||||
}
|
||||
millisecond: true,
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper.emitted('finish')).toBeFalsy();
|
||||
@@ -33,8 +30,8 @@ test('macro task re-render', async () => {
|
||||
const wrapper = mount(CountDown, {
|
||||
propsData: {
|
||||
time: 1000,
|
||||
format: 'SSS'
|
||||
}
|
||||
format: 'SSS',
|
||||
},
|
||||
});
|
||||
|
||||
const prevSnapShot = wrapper.html();
|
||||
@@ -49,8 +46,8 @@ test('micro task re-render', async () => {
|
||||
propsData: {
|
||||
time: 100,
|
||||
format: 'SSS',
|
||||
millisecond: true
|
||||
}
|
||||
millisecond: true,
|
||||
},
|
||||
});
|
||||
|
||||
const prevSnapShot = wrapper.html();
|
||||
@@ -65,8 +62,8 @@ test('disable auto-start prop', async () => {
|
||||
propsData: {
|
||||
time: 100,
|
||||
format: 'SSS',
|
||||
autoStart: false
|
||||
}
|
||||
autoStart: false,
|
||||
},
|
||||
});
|
||||
|
||||
await later(50);
|
||||
@@ -79,8 +76,8 @@ test('start method', async () => {
|
||||
time: 100,
|
||||
format: 'SSS',
|
||||
autoStart: false,
|
||||
millisecond: true
|
||||
}
|
||||
millisecond: true,
|
||||
},
|
||||
});
|
||||
|
||||
const prevSnapShot = wrapper.html();
|
||||
@@ -100,8 +97,8 @@ test('pause method', async () => {
|
||||
propsData: {
|
||||
time: 100,
|
||||
format: 'SSS',
|
||||
millisecond: true
|
||||
}
|
||||
millisecond: true,
|
||||
},
|
||||
});
|
||||
|
||||
const prevSnapShot = wrapper.html();
|
||||
@@ -117,8 +114,8 @@ test('reset method', async () => {
|
||||
propsData: {
|
||||
time: 100,
|
||||
format: 'SSS',
|
||||
millisecond: true
|
||||
}
|
||||
millisecond: true,
|
||||
},
|
||||
});
|
||||
|
||||
const prevSnapShot = wrapper.html();
|
||||
@@ -134,8 +131,8 @@ test('complete format prop', () => {
|
||||
propsData: {
|
||||
time: 30 * 60 * 60 * 1000 - 1,
|
||||
autoStart: false,
|
||||
format: 'DD-HH-mm-ss-SSS'
|
||||
}
|
||||
format: 'DD-HH-mm-ss-SSS',
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
@@ -146,8 +143,8 @@ test('milliseconds format SS', () => {
|
||||
propsData: {
|
||||
time: 1500,
|
||||
autoStart: false,
|
||||
format: 'ss-SS'
|
||||
}
|
||||
format: 'ss-SS',
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
@@ -158,8 +155,8 @@ test('milliseconds format S', () => {
|
||||
propsData: {
|
||||
time: 1500,
|
||||
autoStart: false,
|
||||
format: 'ss-S'
|
||||
}
|
||||
format: 'ss-S',
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
@@ -170,8 +167,8 @@ test('incomplate format prop', () => {
|
||||
propsData: {
|
||||
time: 30 * 60 * 60 * 1000 - 1,
|
||||
autoStart: false,
|
||||
format: 'HH-mm-ss-SSS'
|
||||
}
|
||||
format: 'HH-mm-ss-SSS',
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
@@ -193,14 +190,14 @@ test('pause when deactivated', async () => {
|
||||
`,
|
||||
data() {
|
||||
return {
|
||||
render: true
|
||||
render: true,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
getCountDown() {
|
||||
return this.$refs.countDown;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const countDown = wrapper.vm.getCountDown();
|
||||
@@ -216,3 +213,21 @@ test('pause when deactivated', async () => {
|
||||
wrapper.setData({ render: true });
|
||||
expect(countDown.counting).toBeFalsy();
|
||||
});
|
||||
|
||||
test('change event', async () => {
|
||||
const wrapper = mount(CountDown, {
|
||||
propsData: {
|
||||
time: 1,
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper.emitted('change')).toBeFalsy();
|
||||
await later(50);
|
||||
expect(wrapper.emitted('change')[0][0]).toEqual({
|
||||
days: 0,
|
||||
hours: 0,
|
||||
milliseconds: 0,
|
||||
minutes: 0,
|
||||
seconds: 0,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -25,7 +25,7 @@ export function parseTimeData(time: number): TimeData {
|
||||
hours,
|
||||
minutes,
|
||||
seconds,
|
||||
milliseconds
|
||||
milliseconds,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+14
-11
@@ -1,5 +1,8 @@
|
||||
// Utils
|
||||
import { createNamespace } from '../utils';
|
||||
import { inherit } from '../utils/functional';
|
||||
|
||||
// Components
|
||||
import Cell from '../cell';
|
||||
|
||||
// Types
|
||||
@@ -13,14 +16,14 @@ export type CouponCellProps = {
|
||||
coupons: Coupon[];
|
||||
currency: string;
|
||||
editable: boolean;
|
||||
chosenCoupon: number;
|
||||
chosenCoupon: number | string;
|
||||
};
|
||||
|
||||
const [createComponent, bem, t] = createNamespace('coupon-cell');
|
||||
|
||||
function formatValue(props: CouponCellProps) {
|
||||
const { coupons, chosenCoupon, currency } = props;
|
||||
const coupon = coupons[chosenCoupon];
|
||||
const coupon = coupons[+chosenCoupon];
|
||||
|
||||
if (coupon) {
|
||||
const value = coupon.value || coupon.denominations || 0;
|
||||
@@ -36,7 +39,7 @@ function CouponCell(
|
||||
slots: DefaultSlots,
|
||||
ctx: RenderContext<CouponCellProps>
|
||||
) {
|
||||
const valueClass = props.coupons[props.chosenCoupon]
|
||||
const valueClass = props.coupons[+props.chosenCoupon]
|
||||
? 'van-coupon-cell--selected'
|
||||
: '';
|
||||
const value = formatValue(props);
|
||||
@@ -55,31 +58,31 @@ function CouponCell(
|
||||
}
|
||||
|
||||
CouponCell.model = {
|
||||
prop: 'chosenCoupon'
|
||||
prop: 'chosenCoupon',
|
||||
};
|
||||
|
||||
CouponCell.props = {
|
||||
title: String,
|
||||
coupons: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
default: () => [],
|
||||
},
|
||||
currency: {
|
||||
type: String,
|
||||
default: '¥'
|
||||
default: '¥',
|
||||
},
|
||||
border: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
default: true,
|
||||
},
|
||||
editable: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
default: true,
|
||||
},
|
||||
chosenCoupon: {
|
||||
type: Number,
|
||||
default: -1
|
||||
}
|
||||
type: [Number, String],
|
||||
default: -1,
|
||||
},
|
||||
};
|
||||
|
||||
export default createComponent<CouponCellProps>(CouponCell);
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
|
||||
### Install
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
import Vue from 'vue';
|
||||
import { CouponCell, CouponList } from 'vant';
|
||||
|
||||
Vue.use(CouponCell).use(CouponList);
|
||||
Vue.use(CouponCell);
|
||||
Vue.use(CouponList);
|
||||
```
|
||||
|
||||
## Usage
|
||||
@@ -20,7 +21,6 @@ Vue.use(CouponCell).use(CouponList);
|
||||
:chosen-coupon="chosenCoupon"
|
||||
@click="showList = true"
|
||||
/>
|
||||
|
||||
<!-- Coupon List -->
|
||||
<van-popup
|
||||
v-model="showList"
|
||||
@@ -38,7 +38,7 @@ Vue.use(CouponCell).use(CouponList);
|
||||
</van-popup>
|
||||
```
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const coupon = {
|
||||
available: 1,
|
||||
originCondition: 0,
|
||||
@@ -59,7 +59,6 @@ export default {
|
||||
disabledCoupons: [coupon]
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
onChange(index) {
|
||||
this.showList = false;
|
||||
@@ -79,7 +78,7 @@ export default {
|
||||
| Attribute | Description | Type | Default |
|
||||
|------|------|------|------|
|
||||
| title | Cell title | *string* | `Coupon` |
|
||||
| chosen-coupon | Index of chosen coupon | *number* | `-1` |
|
||||
| chosen-coupon | Index of chosen coupon | *number \| string* | `-1` |
|
||||
| coupons | Coupon list | *Coupon[]* | `[]` |
|
||||
| editable | Cell editable | *boolean* | `true` |
|
||||
| border | Whether to show innner border | *boolean* | `true` |
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
|
||||
### 引入
|
||||
|
||||
``` javascript
|
||||
```js
|
||||
import Vue from 'vue';
|
||||
import { CouponCell, CouponList } from 'vant';
|
||||
|
||||
Vue.use(CouponCell).use(CouponList);
|
||||
Vue.use(CouponCell);
|
||||
Vue.use(CouponList);
|
||||
```
|
||||
|
||||
## 代码演示
|
||||
@@ -20,7 +21,6 @@ Vue.use(CouponCell).use(CouponList);
|
||||
:chosen-coupon="chosenCoupon"
|
||||
@click="showList = true"
|
||||
/>
|
||||
|
||||
<!-- 优惠券列表 -->
|
||||
<van-popup
|
||||
v-model="showList"
|
||||
@@ -38,7 +38,7 @@ Vue.use(CouponCell).use(CouponList);
|
||||
</van-popup>
|
||||
```
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const coupon = {
|
||||
available: 1,
|
||||
condition: '无使用门槛\n最多优惠12元',
|
||||
@@ -59,7 +59,6 @@ export default {
|
||||
disabledCoupons: [coupon]
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
onChange(index) {
|
||||
this.showList = false;
|
||||
@@ -79,7 +78,7 @@ export default {
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|------|------|------|------|
|
||||
| title | 单元格标题 | *string* | `优惠券` |
|
||||
| chosen-coupon | 当前选中优惠券的索引 | *number* | `-1` |
|
||||
| chosen-coupon | 当前选中优惠券的索引 | *number \| string* | `-1` |
|
||||
| coupons | 可用优惠券列表 | *Coupon[]* | `[]` |
|
||||
| editable | 能否切换优惠券 | *boolean* | `true` |
|
||||
| border | 是否显示内边框 | *boolean* | `true` |
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user