mirror of
https://gitee.com/vant-contrib/vant-weapp.git
synced 2025-04-06 03:58:05 +08:00
feat(Collapse): add new component Collapse @rex-zsd (#936)
This commit is contained in:
parent
902f4d4368
commit
559dde9616
docs/src
example
packages
cell
collapse-item
collapse
@ -49,7 +49,8 @@ const MAP = {
|
||||
transition: 'transition-20180821.png',
|
||||
'tree-select': 'tree-select-201808092138.png',
|
||||
checkbox: 'checkbox-20181110.jpeg',
|
||||
rate: 'rate-20181120-1.png'
|
||||
rate: 'rate-20181120-1.png',
|
||||
collapse: 'collapse-20181123.png'
|
||||
};
|
||||
|
||||
export default {
|
||||
|
@ -36,7 +36,8 @@
|
||||
"pages/goods-action/index",
|
||||
"pages/swipe-cell/index",
|
||||
"pages/datetime-picker/index",
|
||||
"pages/rate/index"
|
||||
"pages/rate/index",
|
||||
"pages/collapse/index"
|
||||
],
|
||||
"window": {
|
||||
"navigationBarBackgroundColor": "#f8f8f8",
|
||||
@ -91,6 +92,8 @@
|
||||
"van-transition": "../../dist/transition/index",
|
||||
"van-tree-select": "../../dist/tree-select/index",
|
||||
"van-datetime-picker": "../../dist/datetime-picker/index",
|
||||
"van-rate": "../../dist/rate/index"
|
||||
"van-rate": "../../dist/rate/index",
|
||||
"van-collapse": "../../dist/collapse/index",
|
||||
"van-collapse-item": "../../dist/collapse-item/index"
|
||||
}
|
||||
}
|
||||
|
@ -109,6 +109,10 @@ export default [
|
||||
path: '/notice-bar',
|
||||
title: 'NoticeBar 通告栏'
|
||||
},
|
||||
{
|
||||
path: '/collapse',
|
||||
title: 'Collapse 折叠面板'
|
||||
},
|
||||
{
|
||||
path: '/panel',
|
||||
title: 'Panel 面板'
|
||||
|
21
example/pages/collapse/index.js
Normal file
21
example/pages/collapse/index.js
Normal file
@ -0,0 +1,21 @@
|
||||
import Page from '../../common/page';
|
||||
|
||||
Page({
|
||||
data: {
|
||||
active1: [0],
|
||||
active2: 0,
|
||||
active3: [],
|
||||
title1: '有赞微商城',
|
||||
title2: '有赞零售',
|
||||
title3: '有赞美业',
|
||||
content1: '提供多样店铺模板,快速搭建网上商城',
|
||||
content2: '网店吸粉获客、会员分层营销、一机多种收款,告别经营低效和客户流失',
|
||||
content3: '线上拓客,随时预约,贴心顺手的开单收银'
|
||||
},
|
||||
onChange(event) {
|
||||
const { key } = event.currentTarget.dataset;
|
||||
this.setData({
|
||||
[key]: event.detail
|
||||
});
|
||||
}
|
||||
});
|
3
example/pages/collapse/index.json
Normal file
3
example/pages/collapse/index.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"navigationBarTitleText": "Collapse 折叠面板"
|
||||
}
|
37
example/pages/collapse/index.wxml
Normal file
37
example/pages/collapse/index.wxml
Normal file
@ -0,0 +1,37 @@
|
||||
<demo-block title="基础用法">
|
||||
<van-collapse value="{{ active1 }}" data-key="active1" bind:change="onChange">
|
||||
<van-collapse-item title="{{ title1 }}" content-class="van-collapse-item__content">{{ content1 }}</van-collapse-item>
|
||||
<van-collapse-item title="{{ title2 }}" content-class="van-collapse-item__content">{{ content2 }}</van-collapse-item>
|
||||
<van-collapse-item
|
||||
title="{{ title3 }}"
|
||||
content-class="van-collapse-item__content"
|
||||
disabled
|
||||
>
|
||||
{{ content3 }}
|
||||
</van-collapse-item>
|
||||
</van-collapse>
|
||||
</demo-block>
|
||||
|
||||
<demo-block title="手风琴">
|
||||
<van-collapse value="{{ active2 }}" data-key="active2" accordion bind:change="onChange">
|
||||
<van-collapse-item title="{{ title1 }}" content-class="van-collapse-item__content">{{ content1 }}</van-collapse-item>
|
||||
<van-collapse-item title="{{ title2 }}" content-class="van-collapse-item__content">{{ content2 }}</van-collapse-item>
|
||||
<van-collapse-item title="{{ title3 }}" content-class="van-collapse-item__content">{{ content3 }}</van-collapse-item>
|
||||
</van-collapse>
|
||||
</demo-block>
|
||||
|
||||
<demo-block title="自定义标题内容">
|
||||
<van-collapse value="{{ active3 }}" data-key="active3" bind:change="onChange">
|
||||
<van-collapse-item content-class="van-collapse-item__content">
|
||||
<view slot="title">{{ title1 }}<van-icon name="question" custom-class="van-icon-question" /></view>
|
||||
{{ content1 }}
|
||||
</van-collapse-item>
|
||||
<van-collapse-item
|
||||
title="{{ title2 }}"
|
||||
content-class="van-collapse-item__content"
|
||||
value="内容"
|
||||
icon="shop"
|
||||
>{{ content2 }}</van-collapse-item>
|
||||
<van-collapse-item title="{{ title3 }}" content-class="van-collapse-item__content">{{ content3 }}</van-collapse-item>
|
||||
</van-collapse>
|
||||
</demo-block>
|
12
example/pages/collapse/index.wxss
Normal file
12
example/pages/collapse/index.wxss
Normal file
@ -0,0 +1,12 @@
|
||||
.van-collapse-item__content {
|
||||
font-size: 13px;
|
||||
line-height: 1.5;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.van-icon-question {
|
||||
margin-left: 5px;
|
||||
font-size: 15px !important;
|
||||
color: #1989fa;
|
||||
vertical-align: -3px;
|
||||
}
|
@ -54,10 +54,13 @@
|
||||
|
||||
&__left-icon-wrap {
|
||||
margin-right: 5px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
&__right-icon-wrap {
|
||||
margin-left: 5px;
|
||||
font-size: 12px;
|
||||
color: @gray-dark;
|
||||
|
||||
&--left {
|
||||
transform: rotate(180deg);
|
||||
@ -73,14 +76,11 @@
|
||||
}
|
||||
|
||||
&__left-icon {
|
||||
font-size: 16px !important;
|
||||
line-height: 24px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
&__right-icon {
|
||||
color: @gray-dark;
|
||||
font-size: 12px !important;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,8 @@ VantComponent({
|
||||
classes: [
|
||||
'title-class',
|
||||
'label-class',
|
||||
'value-class'
|
||||
'value-class',
|
||||
'right-icon-class'
|
||||
],
|
||||
|
||||
mixins: [link],
|
||||
@ -47,7 +48,7 @@ VantComponent({
|
||||
},
|
||||
|
||||
iconWrapClass(): string {
|
||||
const prefix = 'van-cell__right-icon-wrap';
|
||||
const prefix = 'van-cell__right-icon-wrap right-icon-class';
|
||||
return this.classNames(prefix, `${prefix}--${this.data.arrowDirection}`);
|
||||
}
|
||||
},
|
||||
|
6
packages/collapse-item/index.json
Normal file
6
packages/collapse-item/index.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {
|
||||
"van-cell": "../cell/index"
|
||||
}
|
||||
}
|
38
packages/collapse-item/index.less
Normal file
38
packages/collapse-item/index.less
Normal file
@ -0,0 +1,38 @@
|
||||
@import '../common/style/var.less';
|
||||
|
||||
.van-collapse-item {
|
||||
&__title {
|
||||
.van-cell__right-icon {
|
||||
transform: rotate(90deg);
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
&--expanded {
|
||||
.van-cell__right-icon {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
}
|
||||
|
||||
&--disabled {
|
||||
& .van-cell,
|
||||
& .van-cell__right-icon {
|
||||
color: @gray !important;
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: @white !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__wrapper {
|
||||
overflow: hidden;
|
||||
will-change: max-height;
|
||||
transition: max-height 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
&__content {
|
||||
padding: 15px;
|
||||
background-color: @white;
|
||||
}
|
||||
}
|
96
packages/collapse-item/index.ts
Normal file
96
packages/collapse-item/index.ts
Normal file
@ -0,0 +1,96 @@
|
||||
import { VantComponent } from '../common/component';
|
||||
|
||||
VantComponent({
|
||||
classes: ['content-class'],
|
||||
|
||||
relation: {
|
||||
name: 'collapse',
|
||||
type: 'ancestor',
|
||||
linked(parent: Weapp.Component) {
|
||||
this.parent = parent;
|
||||
}
|
||||
},
|
||||
|
||||
props: {
|
||||
name: [String, Number],
|
||||
icon: String,
|
||||
label: String,
|
||||
title: [String, Number],
|
||||
value: [String, Number],
|
||||
disabled: Boolean,
|
||||
border: {
|
||||
type: Boolean,
|
||||
value: true
|
||||
},
|
||||
isLink: {
|
||||
type: Boolean,
|
||||
value: true
|
||||
}
|
||||
},
|
||||
|
||||
data: {
|
||||
contentHeight: 0,
|
||||
expanded: false
|
||||
},
|
||||
|
||||
computed: {
|
||||
titleClass() {
|
||||
const { disabled, expanded } = this.data;
|
||||
return this.classNames('van-collapse-item__title', {
|
||||
'van-collapse-item__title--disabled': disabled,
|
||||
'van-collapse-item__title--expanded': expanded
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
updateExpanded() {
|
||||
if (!this.parent) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { value, accordion, items } = this.parent.data;
|
||||
const { name } = this.data;
|
||||
|
||||
const index = items.indexOf(this);
|
||||
const currentName = name == null ? index : name;
|
||||
|
||||
const expanded = accordion
|
||||
? value === currentName
|
||||
: value.some(name => name === currentName);
|
||||
|
||||
if (expanded !== this.data.expanded) {
|
||||
this.updateStyle(expanded);
|
||||
}
|
||||
|
||||
this.setData({ expanded });
|
||||
},
|
||||
|
||||
updateStyle(expanded) {
|
||||
if (expanded) {
|
||||
this.getRect('.van-collapse-item__content').then(res => {
|
||||
this.setData({
|
||||
contentHeight: res.height ? res.height + 'px' : null
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.setData({
|
||||
contentHeight: 0
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
onClick() {
|
||||
if (this.data.disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { name, expanded } = this.data;
|
||||
|
||||
const index = this.parent.data.items.indexOf(this);
|
||||
const currentName = name == null ? index : name;
|
||||
|
||||
this.parent.switch(currentName, !expanded);
|
||||
}
|
||||
}
|
||||
});
|
39
packages/collapse-item/index.wxml
Normal file
39
packages/collapse-item/index.wxml
Normal file
@ -0,0 +1,39 @@
|
||||
<view class="van-collapse-item van-hairline--top custom-class">
|
||||
<van-cell
|
||||
title="{{ title }}"
|
||||
icon="{{ icon }}"
|
||||
is-link="{{ isLink }}"
|
||||
value="{{ value }}"
|
||||
label="{{ label }}"
|
||||
border="{{ border && expanded }}"
|
||||
class="{{ titleClass }}"
|
||||
right-icon-class="van-cell__right-icon"
|
||||
custom-class="van-cell"
|
||||
arrow-direction="{{ expanded ? 'up' : 'down' }}"
|
||||
bind:click="onClick"
|
||||
>
|
||||
<slot
|
||||
name="title"
|
||||
slot="title"
|
||||
/>
|
||||
<slot
|
||||
name="icon"
|
||||
slot="icon"
|
||||
/>
|
||||
<slot name="value" />
|
||||
<slot
|
||||
name="right-icon"
|
||||
slot="right-icon"
|
||||
/>
|
||||
</van-cell>
|
||||
<view
|
||||
class="van-collapse-item__wrapper"
|
||||
style="max-height: {{ contentHeight }};"
|
||||
>
|
||||
<view
|
||||
class="van-collapse-item__content content-class"
|
||||
>
|
||||
<slot />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
127
packages/collapse/README.md
Normal file
127
packages/collapse/README.md
Normal file
@ -0,0 +1,127 @@
|
||||
## Collapse 折叠面板
|
||||
|
||||
### 使用指南
|
||||
在 app.json 或 index.json 中引入组件
|
||||
```json
|
||||
"usingComponents": {
|
||||
"van-collapse": "path/to/vant-weapp/dist/collapse/index",
|
||||
"van-collapse-item": "path/to/vant-weapp/dist/collapse-item/index"
|
||||
}
|
||||
```
|
||||
|
||||
### 代码演示
|
||||
|
||||
#### 基础用法
|
||||
通过`value`控制展开的面板列表,`activeNames`为数组格式
|
||||
|
||||
```html
|
||||
<van-collapse value="{{ 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" disabled>
|
||||
线上拓客,随时预约,贴心顺手的开单收银
|
||||
</van-collapse-item>
|
||||
</van-collapse>
|
||||
```
|
||||
|
||||
``` javascript
|
||||
Page({
|
||||
data: {
|
||||
activeNames: ['1']
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
#### 手风琴
|
||||
通过`accordion`可以设置为手风琴模式,最多展开一个面板,此时`activeName`为字符串格式
|
||||
|
||||
```html
|
||||
<van-collapse value="{{ 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
|
||||
Page({
|
||||
data: {
|
||||
activeName: '1'
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
#### 自定义标题内容
|
||||
|
||||
```html
|
||||
<van-collapse value="{{ activeNames }}">
|
||||
<van-collapse-item name="1">
|
||||
<view slot="title">有赞微商城<van-icon name="question" /></view>
|
||||
提供多样店铺模板,快速搭建网上商城
|
||||
</van-collapse-item>
|
||||
<van-collapse-item title="有赞零售" name="2">
|
||||
网店吸粉获客、会员分层营销、一机多种收款,告别经营低效和客户流失
|
||||
</van-collapse-item>
|
||||
</van-collapse>
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Collapse API
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
|------|------|------|------|------|
|
||||
| value | 当前展开面板的 name | `Array | String | Number` | - |
|
||||
| accordion | 是否开启手风琴模式 | `Boolean` | `false` |
|
||||
|
||||
### Collapse Event
|
||||
|
||||
| 事件名 | 说明 | 参数 |
|
||||
|------|------|------|
|
||||
| change | 切换面板时触发 | activeNames: `String | Array` |
|
||||
|
||||
### CollapseItem API
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|------|------|------|------|------|
|
||||
| name | 唯一标识符,默认为索引值 | `String | Number` | `index` |
|
||||
| title | 标题栏左侧内容 | `String | Number` | - |
|
||||
| icon | 标题栏左侧图标,可选值见 Icon 组件 | `String` | - |
|
||||
| value | 标题栏右侧内容 | `String | Number` | - |
|
||||
| label | 标题栏描述信息 | `String` | - |
|
||||
| border | 是否显示内边框 | `Boolean` | `true` |
|
||||
| is-link | 是否展示标题栏右侧箭头并开启点击反馈 | `Boolean` | `true` |
|
||||
| disabled | 是否禁用面板 | `Boolean` | `false` |
|
||||
|
||||
### CollapseItem Slot
|
||||
|
||||
| 名称 | 说明 |
|
||||
|------|------|
|
||||
| - | 面板内容 |
|
||||
| value | 自定义显示内容 |
|
||||
| icon | 自定义`icon` |
|
||||
| title | 自定义`title` |
|
||||
| right-icon | 自定义右侧按钮,默认是`arrow` |
|
||||
|
||||
### Collapse 外部样式类
|
||||
|
||||
| 类名 | 说明 |
|
||||
|-----------|-----------|
|
||||
| custom-class | 根节点样式类 |
|
||||
|
||||
### CollapseItem 外部样式类
|
||||
|
||||
| 类名 | 说明 |
|
||||
|-----------|-----------|
|
||||
| custom-class | 根节点样式类 |
|
||||
| content-class | 内容样式类 |
|
3
packages/collapse/index.json
Normal file
3
packages/collapse/index.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"component": true
|
||||
}
|
52
packages/collapse/index.ts
Normal file
52
packages/collapse/index.ts
Normal file
@ -0,0 +1,52 @@
|
||||
import { VantComponent } from '../common/component';
|
||||
|
||||
VantComponent({
|
||||
relation: {
|
||||
name: 'collapse-item',
|
||||
type: 'descendant',
|
||||
linked(child: Weapp.Component) {
|
||||
this.setData({
|
||||
items: [...this.data.items, child]
|
||||
}, () => {
|
||||
child.updateExpanded();
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
props: {
|
||||
accordion: Boolean,
|
||||
value: null
|
||||
},
|
||||
|
||||
data: {
|
||||
items: []
|
||||
},
|
||||
|
||||
watch: {
|
||||
value() {
|
||||
this.data.items.forEach(child => {
|
||||
child.updateExpanded();
|
||||
});
|
||||
},
|
||||
accordion() {
|
||||
this.data.items.forEach(child => {
|
||||
child.updateExpanded();
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
switch(name, expanded) {
|
||||
const { accordion, value } = this.data;
|
||||
if (!accordion) {
|
||||
name = expanded
|
||||
? value.concat(name)
|
||||
: value.filter(activeName => activeName !== name);
|
||||
} else {
|
||||
name = expanded ? name : '';
|
||||
}
|
||||
this.$emit('change', name);
|
||||
this.$emit('input', name);
|
||||
}
|
||||
}
|
||||
});
|
3
packages/collapse/index.wxml
Normal file
3
packages/collapse/index.wxml
Normal file
@ -0,0 +1,3 @@
|
||||
<view class="van-collapse van-hairline--top-bottom custom-class">
|
||||
<slot />
|
||||
</view>
|
Loading…
x
Reference in New Issue
Block a user