mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
[new feature] add Collapse component (#674)
This commit is contained in:
parent
0b7468f596
commit
0768aab52c
@ -33,6 +33,7 @@ export default {
|
|||||||
'cell': asyncWrapper(r => require.ensure([], () => r(componentWrapper(require('./views/cell'), 'cell')), 'cell')),
|
'cell': asyncWrapper(r => require.ensure([], () => r(componentWrapper(require('./views/cell'), 'cell')), 'cell')),
|
||||||
'checkbox': asyncWrapper(r => require.ensure([], () => r(componentWrapper(require('./views/checkbox'), 'checkbox')), 'checkbox')),
|
'checkbox': asyncWrapper(r => require.ensure([], () => r(componentWrapper(require('./views/checkbox'), 'checkbox')), 'checkbox')),
|
||||||
'circle': asyncWrapper(r => require.ensure([], () => r(componentWrapper(require('./views/circle'), 'circle')), 'circle')),
|
'circle': asyncWrapper(r => require.ensure([], () => r(componentWrapper(require('./views/circle'), 'circle')), 'circle')),
|
||||||
|
'collapse': asyncWrapper(r => require.ensure([], () => r(componentWrapper(require('./views/collapse'), 'collapse')), 'collapse')),
|
||||||
'contact': asyncWrapper(r => require.ensure([], () => r(componentWrapper(require('./views/contact'), 'contact')), 'contact')),
|
'contact': asyncWrapper(r => require.ensure([], () => r(componentWrapper(require('./views/contact'), 'contact')), 'contact')),
|
||||||
'coupon': asyncWrapper(r => require.ensure([], () => r(componentWrapper(require('./views/coupon'), 'coupon')), 'coupon')),
|
'coupon': asyncWrapper(r => require.ensure([], () => r(componentWrapper(require('./views/coupon'), 'coupon')), 'coupon')),
|
||||||
'datetime-picker': asyncWrapper(r => require.ensure([], () => r(componentWrapper(require('./views/datetime-picker'), 'datetime-picker')), 'datetime-picker')),
|
'datetime-picker': asyncWrapper(r => require.ensure([], () => r(componentWrapper(require('./views/datetime-picker'), 'datetime-picker')), 'datetime-picker')),
|
||||||
|
83
docs/demos/views/collapse.vue
Normal file
83
docs/demos/views/collapse.vue
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
<template>
|
||||||
|
<demo-section>
|
||||||
|
<demo-block :title="$t('basicUsage')">
|
||||||
|
<van-collapse v-model="active1">
|
||||||
|
<van-collapse-item :title="$t('title1')">{{ $t('content1') }}</van-collapse-item>
|
||||||
|
<van-collapse-item :title="$t('title2')">{{ $t('content2') }}</van-collapse-item>
|
||||||
|
<van-collapse-item :title="$t('title3')">{{ $t('content3') }}</van-collapse-item>
|
||||||
|
</van-collapse>
|
||||||
|
</demo-block>
|
||||||
|
|
||||||
|
<demo-block :title="$t('accordion')">
|
||||||
|
<van-collapse v-model="active2" accordion>
|
||||||
|
<van-collapse-item :title="$t('title1')">{{ $t('content1') }}</van-collapse-item>
|
||||||
|
<van-collapse-item :title="$t('title2')">{{ $t('content2') }}</van-collapse-item>
|
||||||
|
<van-collapse-item :title="$t('title3')">{{ $t('content3') }}</van-collapse-item>
|
||||||
|
</van-collapse>
|
||||||
|
</demo-block>
|
||||||
|
|
||||||
|
<demo-block :title="$t('titleSlot')">
|
||||||
|
<van-collapse v-model="active3">
|
||||||
|
<van-collapse-item>
|
||||||
|
<div slot="title">{{ $t('title1') }}<van-icon name="question" /></div>
|
||||||
|
{{ $t('content1') }}
|
||||||
|
</van-collapse-item>
|
||||||
|
<van-collapse-item :title="$t('title2')">{{ $t('content2') }}</van-collapse-item>
|
||||||
|
</van-collapse>
|
||||||
|
</demo-block>
|
||||||
|
</demo-section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
i18n: {
|
||||||
|
'zh-CN': {
|
||||||
|
accordion: '手风琴',
|
||||||
|
titleSlot: '自定义标题内容',
|
||||||
|
title1: '有赞微商城',
|
||||||
|
title2: '有赞零售',
|
||||||
|
title3: '有赞美业',
|
||||||
|
content1: '提供多样店铺模板,快速搭建网上商城',
|
||||||
|
content2: '网店吸粉获客、会员分层营销、一机多种收款,告别经营低效和客户流失',
|
||||||
|
content3: '线上拓客,随时预约,贴心顺手的开单收银'
|
||||||
|
},
|
||||||
|
'en-US': {
|
||||||
|
accordion: 'Accordion',
|
||||||
|
titleSlot: 'Custom title',
|
||||||
|
title1: 'Title1',
|
||||||
|
title2: 'Title2',
|
||||||
|
title3: 'Title3',
|
||||||
|
content1: 'Only those who have the patience to do simple things perfectly ever acquire the skill to do difficult things easily.',
|
||||||
|
content2: 'When someone walk out your life, let them. They are just making more room for someone else better to walk in.',
|
||||||
|
content3: 'The world is big and life is short. Live the life the way you want.'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
active1: [0],
|
||||||
|
active2: 0,
|
||||||
|
active3: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="postcss">
|
||||||
|
@import "../../../packages/vant-css/src/common/var.css";
|
||||||
|
|
||||||
|
.demo-collapse {
|
||||||
|
.van-collapse-item__content {
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 1.5;
|
||||||
|
color: $gray-darker;
|
||||||
|
}
|
||||||
|
|
||||||
|
.van-icon-question {
|
||||||
|
color: $blue;
|
||||||
|
vertical-align: -3px;
|
||||||
|
margin-left: 5px;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
95
docs/markdown/en-US/collapse.md
Normal file
95
docs/markdown/en-US/collapse.md
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
## Collapse
|
||||||
|
|
||||||
|
### Install
|
||||||
|
``` javascript
|
||||||
|
import { Collapse } from 'vant';
|
||||||
|
|
||||||
|
Vue.use(Collapse);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
#### Basic Usage
|
||||||
|
Use `v-model` to control the name of active panels
|
||||||
|
|
||||||
|
```html
|
||||||
|
<van-collapse v-model="activeNames">
|
||||||
|
<van-collapse-item title="Title1" name="1">Content</van-collapse-item>
|
||||||
|
<van-collapse-item title="Title2" name="2">Content</van-collapse-item>
|
||||||
|
<van-collapse-item title="Title3" name="3">Content</van-collapse-item>
|
||||||
|
</van-collapse>
|
||||||
|
```
|
||||||
|
|
||||||
|
``` javascript
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
activeNames: ['1']
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Accordion
|
||||||
|
In accordion mode, only one panel can be expanded at the same time.
|
||||||
|
|
||||||
|
```html
|
||||||
|
<van-collapse v-model="activeName" accordion>
|
||||||
|
<van-collapse-item title="Title1" name="1">Content</van-collapse-item>
|
||||||
|
<van-collapse-item title="Title2" name="2">Content</van-collapse-item>
|
||||||
|
<van-collapse-item title="Title3" name="3">Content</van-collapse-item>
|
||||||
|
</van-collapse>
|
||||||
|
```
|
||||||
|
|
||||||
|
``` javascript
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
activeName: '1'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Custom title
|
||||||
|
|
||||||
|
```html
|
||||||
|
<van-collapse v-model="activeNames">
|
||||||
|
<van-collapse-item name="1">
|
||||||
|
<div slot="title">Title1<van-icon name="question" /></div>
|
||||||
|
Content
|
||||||
|
</van-collapse-item>
|
||||||
|
<van-collapse-item title="Title2" name="2">
|
||||||
|
Content
|
||||||
|
</van-collapse-item>
|
||||||
|
</van-collapse>
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Collapse API
|
||||||
|
|
||||||
|
| Attribute | Description | Type | Default | Accepted Values |
|
||||||
|
|-----------|-----------|-----------|-------------|-------------|
|
||||||
|
| v-model | names of current active panels | `Array | String | Number` | - | - |
|
||||||
|
| accordion | Whether to be accordion mode | `Boolean` | `false` | - |
|
||||||
|
|
||||||
|
### Collapse Event
|
||||||
|
|
||||||
|
| Event | Description | Arguments |
|
||||||
|
|-----------|-----------|-----------|
|
||||||
|
| change | Triggered when switch panel | activeNames: `string | array` |
|
||||||
|
|
||||||
|
### CollapseItem API
|
||||||
|
|
||||||
|
| Attribute | Description | Type | Default | Accepted Values |
|
||||||
|
|-----------|-----------|-----------|-------------|-------------|
|
||||||
|
| name | Name | `String | Number` | `index` | - |
|
||||||
|
| title | Title | `String` | - | - |
|
||||||
|
|
||||||
|
### CollapseItem Slot
|
||||||
|
|
||||||
|
| name | Description |
|
||||||
|
|-----------|-----------|
|
||||||
|
| default | Content |
|
||||||
|
| title | Custom title |
|
@ -27,6 +27,7 @@ export default {
|
|||||||
'zh-CN/changelog': wrapper(r => require.ensure([], () => r(require('./zh-CN/changelog.md')), 'zh-CN/changelog')),
|
'zh-CN/changelog': wrapper(r => require.ensure([], () => r(require('./zh-CN/changelog.md')), 'zh-CN/changelog')),
|
||||||
'zh-CN/checkbox': wrapper(r => require.ensure([], () => r(require('./zh-CN/checkbox.md')), 'zh-CN/checkbox')),
|
'zh-CN/checkbox': wrapper(r => require.ensure([], () => r(require('./zh-CN/checkbox.md')), 'zh-CN/checkbox')),
|
||||||
'zh-CN/circle': wrapper(r => require.ensure([], () => r(require('./zh-CN/circle.md')), 'zh-CN/circle')),
|
'zh-CN/circle': wrapper(r => require.ensure([], () => r(require('./zh-CN/circle.md')), 'zh-CN/circle')),
|
||||||
|
'zh-CN/collapse': wrapper(r => require.ensure([], () => r(require('./zh-CN/collapse.md')), 'zh-CN/collapse')),
|
||||||
'zh-CN/contact': wrapper(r => require.ensure([], () => r(require('./zh-CN/contact.md')), 'zh-CN/contact')),
|
'zh-CN/contact': wrapper(r => require.ensure([], () => r(require('./zh-CN/contact.md')), 'zh-CN/contact')),
|
||||||
'zh-CN/coupon': wrapper(r => require.ensure([], () => r(require('./zh-CN/coupon.md')), 'zh-CN/coupon')),
|
'zh-CN/coupon': wrapper(r => require.ensure([], () => r(require('./zh-CN/coupon.md')), 'zh-CN/coupon')),
|
||||||
'zh-CN/datetime-picker': wrapper(r => require.ensure([], () => r(require('./zh-CN/datetime-picker.md')), 'zh-CN/datetime-picker')),
|
'zh-CN/datetime-picker': wrapper(r => require.ensure([], () => r(require('./zh-CN/datetime-picker.md')), 'zh-CN/datetime-picker')),
|
||||||
@ -81,6 +82,7 @@ export default {
|
|||||||
'en-US/changelog': wrapper(r => require.ensure([], () => r(require('./en-US/changelog.md')), 'en-US/changelog')),
|
'en-US/changelog': wrapper(r => require.ensure([], () => r(require('./en-US/changelog.md')), 'en-US/changelog')),
|
||||||
'en-US/checkbox': wrapper(r => require.ensure([], () => r(require('./en-US/checkbox.md')), 'en-US/checkbox')),
|
'en-US/checkbox': wrapper(r => require.ensure([], () => r(require('./en-US/checkbox.md')), 'en-US/checkbox')),
|
||||||
'en-US/circle': wrapper(r => require.ensure([], () => r(require('./en-US/circle.md')), 'en-US/circle')),
|
'en-US/circle': wrapper(r => require.ensure([], () => r(require('./en-US/circle.md')), 'en-US/circle')),
|
||||||
|
'en-US/collapse': wrapper(r => require.ensure([], () => r(require('./en-US/collapse.md')), 'en-US/collapse')),
|
||||||
'en-US/contact': wrapper(r => require.ensure([], () => r(require('./en-US/contact.md')), 'en-US/contact')),
|
'en-US/contact': wrapper(r => require.ensure([], () => r(require('./en-US/contact.md')), 'en-US/contact')),
|
||||||
'en-US/coupon': wrapper(r => require.ensure([], () => r(require('./en-US/coupon.md')), 'en-US/coupon')),
|
'en-US/coupon': wrapper(r => require.ensure([], () => r(require('./en-US/coupon.md')), 'en-US/coupon')),
|
||||||
'en-US/datetime-picker': wrapper(r => require.ensure([], () => r(require('./en-US/datetime-picker.md')), 'en-US/datetime-picker')),
|
'en-US/datetime-picker': wrapper(r => require.ensure([], () => r(require('./en-US/datetime-picker.md')), 'en-US/datetime-picker')),
|
||||||
|
108
docs/markdown/zh-CN/collapse.md
Normal file
108
docs/markdown/zh-CN/collapse.md
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
## Collapse 折叠面板
|
||||||
|
|
||||||
|
### 使用指南
|
||||||
|
``` javascript
|
||||||
|
import { Collapse } from 'vant';
|
||||||
|
|
||||||
|
Vue.use(Collapse);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 代码演示
|
||||||
|
|
||||||
|
#### 基础用法
|
||||||
|
通过`v-model`控制展开的面板列表,`activeNames`为数组格式
|
||||||
|
|
||||||
|
```html
|
||||||
|
<van-collapse v-model="activeNames">
|
||||||
|
<van-collapse-item title="有赞微商城" name="1">
|
||||||
|
提供多样店铺模板,快速搭建网上商城
|
||||||
|
</van-collapse-item>
|
||||||
|
<van-collapse-item title="有赞零售" name="2">
|
||||||
|
网店吸粉获客、会员分层营销、一机多种收款,告别经营低效和客户流失
|
||||||
|
</van-collapse-item>
|
||||||
|
<van-collapse-item title="有赞美业" name="3">
|
||||||
|
线上拓客,随时预约,贴心顺手的开单收银
|
||||||
|
</van-collapse-item>
|
||||||
|
</van-collapse>
|
||||||
|
```
|
||||||
|
|
||||||
|
``` javascript
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
activeNames: ['1']
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 手风琴
|
||||||
|
通过`accordion`可以设置为手风琴模式,最多展开一个面板,此时`activeName`为字符串格式
|
||||||
|
|
||||||
|
```html
|
||||||
|
<van-collapse v-model="activeName" accordion>
|
||||||
|
<van-collapse-item title="有赞微商城" name="1">
|
||||||
|
提供多样店铺模板,快速搭建网上商城
|
||||||
|
</van-collapse-item>
|
||||||
|
<van-collapse-item title="有赞零售" name="2">
|
||||||
|
网店吸粉获客、会员分层营销、一机多种收款,告别经营低效和客户流失
|
||||||
|
</van-collapse-item>
|
||||||
|
<van-collapse-item title="有赞美业" name="3">
|
||||||
|
线上拓客,随时预约,贴心顺手的开单收银
|
||||||
|
</van-collapse-item>
|
||||||
|
</van-collapse>
|
||||||
|
```
|
||||||
|
|
||||||
|
``` javascript
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
activeName: '1'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 自定义标题内容
|
||||||
|
|
||||||
|
```html
|
||||||
|
<van-collapse v-model="activeNames">
|
||||||
|
<van-collapse-item name="1">
|
||||||
|
<div slot="title">有赞微商城<van-icon name="question" /></div>
|
||||||
|
提供多样店铺模板,快速搭建网上商城
|
||||||
|
</van-collapse-item>
|
||||||
|
<van-collapse-item title="有赞零售" name="2">
|
||||||
|
网店吸粉获客、会员分层营销、一机多种收款,告别经营低效和客户流失
|
||||||
|
</van-collapse-item>
|
||||||
|
</van-collapse>
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Collapse API
|
||||||
|
|
||||||
|
| 参数 | 说明 | 类型 | 默认值 | 可选值 |
|
||||||
|
|-----------|-----------|-----------|-------------|-------------|
|
||||||
|
| v-model | 当前展开面板的 name | `Array | String | Number` | - | - |
|
||||||
|
| accordion | 是否开启手风琴模式 | `Boolean` | `false` | - |
|
||||||
|
|
||||||
|
### Collapse Event
|
||||||
|
|
||||||
|
| 事件名 | 说明 | 参数 |
|
||||||
|
|-----------|-----------|-----------|
|
||||||
|
| change | 切换面板时触发 | activeNames: `string | array` |
|
||||||
|
|
||||||
|
### CollapseItem API
|
||||||
|
|
||||||
|
| 参数 | 说明 | 类型 | 默认值 | 可选值 |
|
||||||
|
|-----------|-----------|-----------|-------------|-------------|
|
||||||
|
| name | 面板唯一标识符,默认为索引值 | `String | Number` | `index` | - |
|
||||||
|
| title | 标题 | `String` | - | - |
|
||||||
|
|
||||||
|
|
||||||
|
### CollapseItem Slot
|
||||||
|
|
||||||
|
| 名称 | 说明 |
|
||||||
|
|-----------|-----------|
|
||||||
|
| default | 面板内容 |
|
||||||
|
| title | 自定义标题内容 |
|
@ -88,6 +88,10 @@ module.exports = {
|
|||||||
path: '/circle',
|
path: '/circle',
|
||||||
title: 'Circle - 环形进度条'
|
title: 'Circle - 环形进度条'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/collapse',
|
||||||
|
title: 'Collapse - 折叠面板'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/icon',
|
path: '/icon',
|
||||||
title: 'Icon - 图标'
|
title: 'Icon - 图标'
|
||||||
@ -374,6 +378,10 @@ module.exports = {
|
|||||||
path: '/circle',
|
path: '/circle',
|
||||||
title: 'Circle'
|
title: 'Circle'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/collapse',
|
||||||
|
title: 'Collapse'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/icon',
|
path: '/icon',
|
||||||
title: 'Icon'
|
title: 'Icon'
|
||||||
|
@ -11,8 +11,8 @@
|
|||||||
:error="isError"
|
:error="isError"
|
||||||
:on-icon-click="onIconClick"
|
:on-icon-click="onIconClick"
|
||||||
@input="$emit('input', $event)"
|
@input="$emit('input', $event)"
|
||||||
@focus="handleFocus"
|
@focus="onFocus"
|
||||||
@blur="handleBlur"
|
@blur="onBlur"
|
||||||
>
|
>
|
||||||
<div slot="icon">
|
<div slot="icon">
|
||||||
<span v-if="showIcon && isAndroid" class="van-address-edit-detail__finish-edit">{{ $t('complete') }}</span>
|
<span v-if="showIcon && isAndroid" class="van-address-edit-detail__finish-edit">{{ $t('complete') }}</span>
|
||||||
@ -79,13 +79,13 @@ export default create({
|
|||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
handleFocus(e) {
|
onFocus(e) {
|
||||||
this.isFocused = true;
|
this.isFocused = true;
|
||||||
this.$emit('focus', e);
|
this.$emit('focus', e);
|
||||||
this.$refs.root.scrollIntoView();
|
this.$refs.root.scrollIntoView();
|
||||||
},
|
},
|
||||||
|
|
||||||
handleBlur(e) {
|
onBlur(e) {
|
||||||
// wait for click event finished
|
// wait for click event finished
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.isFocused = false;
|
this.isFocused = false;
|
||||||
|
75
packages/collapse-item/index.vue
Normal file
75
packages/collapse-item/index.vue
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="van-collapse-item"
|
||||||
|
:class="{
|
||||||
|
'van-hairline--top': index,
|
||||||
|
'van-collapse-item--expanded': expanded
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<cell class="van-collapse-item__title" is-link @click="onClick">
|
||||||
|
<slot name="title">{{ title }}</slot>
|
||||||
|
</cell>
|
||||||
|
<div class="van-collapse-item__content" v-show="expanded">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Cell from '../cell';
|
||||||
|
import findParent from '../mixins/find-parent';
|
||||||
|
import { create, isDef } from '../utils';
|
||||||
|
|
||||||
|
export default create({
|
||||||
|
name: 'van-collapse-item',
|
||||||
|
|
||||||
|
mixins: [findParent],
|
||||||
|
|
||||||
|
components: {
|
||||||
|
Cell
|
||||||
|
},
|
||||||
|
|
||||||
|
props: {
|
||||||
|
name: [String, Number],
|
||||||
|
title: String
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
items() {
|
||||||
|
return this.parentGroup.items;
|
||||||
|
},
|
||||||
|
|
||||||
|
index() {
|
||||||
|
return this.items.indexOf(this);
|
||||||
|
},
|
||||||
|
|
||||||
|
currentName() {
|
||||||
|
return isDef(this.name) ? this.name : this.index;
|
||||||
|
},
|
||||||
|
|
||||||
|
expanded() {
|
||||||
|
const { activeNames } = this.parentGroup;
|
||||||
|
return this.parentGroup.accordion
|
||||||
|
? activeNames === this.currentName
|
||||||
|
: activeNames.some(name => name === this.currentName);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
this.findParentByName('van-collapse');
|
||||||
|
this.items.push(this);
|
||||||
|
},
|
||||||
|
|
||||||
|
destroyed() {
|
||||||
|
this.items.splice(this.index, 1);
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
onClick() {
|
||||||
|
const { parentGroup } = this;
|
||||||
|
const name = parentGroup.accordion && this.currentName === parentGroup.activeNames ? '' : this.currentName;
|
||||||
|
this.parentGroup.switch(name, !this.expanded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
41
packages/collapse/index.vue
Normal file
41
packages/collapse/index.vue
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<template>
|
||||||
|
<div class="van-collapse van-hairline--top-bottom">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { create } from '../utils';
|
||||||
|
|
||||||
|
export default create({
|
||||||
|
name: 'van-collapse',
|
||||||
|
|
||||||
|
model: {
|
||||||
|
prop: 'activeNames'
|
||||||
|
},
|
||||||
|
|
||||||
|
props: {
|
||||||
|
accordion: Boolean,
|
||||||
|
activeNames: [String, Number, Array]
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
items: []
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
switch(name, expanded) {
|
||||||
|
const { activeNames } = this;
|
||||||
|
if (!this.accordion) {
|
||||||
|
name = expanded
|
||||||
|
? activeNames.concat(name)
|
||||||
|
: activeNames.filter(activeName => activeName !== name);
|
||||||
|
}
|
||||||
|
this.$emit('change', name);
|
||||||
|
this.$emit('input', name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
@ -14,6 +14,8 @@ import Checkbox from './checkbox';
|
|||||||
import CheckboxGroup from './checkbox-group';
|
import CheckboxGroup from './checkbox-group';
|
||||||
import Circle from './circle';
|
import Circle from './circle';
|
||||||
import Col from './col';
|
import Col from './col';
|
||||||
|
import Collapse from './collapse';
|
||||||
|
import CollapseItem from './collapse-item';
|
||||||
import ContactCard from './contact-card';
|
import ContactCard from './contact-card';
|
||||||
import ContactEdit from './contact-edit';
|
import ContactEdit from './contact-edit';
|
||||||
import ContactList from './contact-list';
|
import ContactList from './contact-list';
|
||||||
@ -80,6 +82,8 @@ const components = [
|
|||||||
CheckboxGroup,
|
CheckboxGroup,
|
||||||
Circle,
|
Circle,
|
||||||
Col,
|
Col,
|
||||||
|
Collapse,
|
||||||
|
CollapseItem,
|
||||||
ContactCard,
|
ContactCard,
|
||||||
ContactEdit,
|
ContactEdit,
|
||||||
ContactList,
|
ContactList,
|
||||||
@ -153,6 +157,8 @@ export {
|
|||||||
CheckboxGroup,
|
CheckboxGroup,
|
||||||
Circle,
|
Circle,
|
||||||
Col,
|
Col,
|
||||||
|
Collapse,
|
||||||
|
CollapseItem,
|
||||||
ContactCard,
|
ContactCard,
|
||||||
ContactEdit,
|
ContactEdit,
|
||||||
ContactList,
|
ContactList,
|
||||||
|
31
packages/vant-css/src/collapse.css
Normal file
31
packages/vant-css/src/collapse.css
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
@import './common/var.css';
|
||||||
|
|
||||||
|
.van-collapse-item {
|
||||||
|
&__title {
|
||||||
|
.van-cell__right-icon::before {
|
||||||
|
transition: .3s;
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__content {
|
||||||
|
padding: 15px;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--expanded {
|
||||||
|
.van-collapse-item__title {
|
||||||
|
.van-cell__right-icon::before {
|
||||||
|
transform: rotate(-90deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -13,6 +13,7 @@
|
|||||||
@import './button.css';
|
@import './button.css';
|
||||||
@import './cell.css';
|
@import './cell.css';
|
||||||
@import './circle.css';
|
@import './circle.css';
|
||||||
|
@import './collapse.css';
|
||||||
@import './loading.css';
|
@import './loading.css';
|
||||||
@import './nav-bar.css';
|
@import './nav-bar.css';
|
||||||
@import './notice-bar.css';
|
@import './notice-bar.css';
|
||||||
|
21
test/components/collapse.vue
Normal file
21
test/components/collapse.vue
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<template>
|
||||||
|
<van-collapse v-model="active" :accordion="accordion">
|
||||||
|
<van-collapse-item title="a" name="first">content</van-collapse-item>
|
||||||
|
<van-collapse-item title="b">content</van-collapse-item>
|
||||||
|
<van-collapse-item title="c">content</van-collapse-item>
|
||||||
|
</van-collapse>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
accordion: Boolean
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
active: this.accordion ? '' : []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
47
test/specs/collapse.spec.js
Normal file
47
test/specs/collapse.spec.js
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
import { mount } from 'avoriaz';
|
||||||
|
import Collapse from '../components/collapse';
|
||||||
|
|
||||||
|
describe('Circle', () => {
|
||||||
|
let wrapper;
|
||||||
|
afterEach(() => {
|
||||||
|
wrapper && wrapper.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('basic mode', () => {
|
||||||
|
wrapper = mount(Collapse);
|
||||||
|
|
||||||
|
const firstTitle = wrapper.find('.van-collapse-item__title')[0];
|
||||||
|
firstTitle.trigger('click');
|
||||||
|
expect(wrapper.vm.active).to.eql(['first']);
|
||||||
|
|
||||||
|
const secondTitle = wrapper.find('.van-collapse-item__title')[1];
|
||||||
|
secondTitle.trigger('click');
|
||||||
|
expect(wrapper.vm.active).to.eql(['first', 1]);
|
||||||
|
|
||||||
|
firstTitle.trigger('click');
|
||||||
|
expect(wrapper.vm.active).to.eql([1]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('accordion', () => {
|
||||||
|
wrapper = mount(Collapse, {
|
||||||
|
propsData: {
|
||||||
|
accordion: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const firstTitle = wrapper.find('.van-collapse-item__title')[0];
|
||||||
|
firstTitle.trigger('click');
|
||||||
|
expect(wrapper.vm.active).to.eql('first');
|
||||||
|
|
||||||
|
const secondTitle = wrapper.find('.van-collapse-item__title')[1];
|
||||||
|
secondTitle.trigger('click');
|
||||||
|
expect(wrapper.vm.active).to.eql(1);
|
||||||
|
|
||||||
|
firstTitle.trigger('click');
|
||||||
|
expect(wrapper.vm.active).to.eql('first');
|
||||||
|
|
||||||
|
firstTitle.trigger('click');
|
||||||
|
expect(wrapper.vm.active).to.eql('');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user