mirror of
https://gitee.com/vant-contrib/vant-weapp.git
synced 2025-04-05 19:41:45 +08:00
[new feature] SwipeCell: add new component swipe-cell
This commit is contained in:
parent
af500d9bd4
commit
40ce5cf61a
@ -33,7 +33,8 @@
|
||||
"pages/submit-bar/index",
|
||||
"pages/radio/index",
|
||||
"pages/checkbox/index",
|
||||
"pages/goods-action/index"
|
||||
"pages/goods-action/index",
|
||||
"pages/swipe-cell/index"
|
||||
],
|
||||
"window": {
|
||||
"navigationBarBackgroundColor": "#f8f8f8",
|
||||
|
@ -125,6 +125,10 @@ export default [
|
||||
{
|
||||
groupName: '高阶组件',
|
||||
list: [
|
||||
{
|
||||
path: '/swipe-cell',
|
||||
title: 'SwipeCell 滑动单元格'
|
||||
},
|
||||
{
|
||||
path: '/switch-cell',
|
||||
title: 'SwitchCell 开关单元格'
|
||||
|
21
example/pages/swipe-cell/index.js
Normal file
21
example/pages/swipe-cell/index.js
Normal file
@ -0,0 +1,21 @@
|
||||
import Page from '../../common/page';
|
||||
import Dialog from '../../dist/dialog/dialog';
|
||||
|
||||
Page({
|
||||
onClose(event) {
|
||||
const { position, instance } = event.detail;
|
||||
switch (position) {
|
||||
case 'left':
|
||||
case 'cell':
|
||||
instance.close();
|
||||
break;
|
||||
case 'right':
|
||||
Dialog.confirm({
|
||||
message: '确定删除吗?'
|
||||
}).then(() => {
|
||||
instance.close();
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
10
example/pages/swipe-cell/index.json
Normal file
10
example/pages/swipe-cell/index.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"navigationBarTitleText": "SwipeCell 滑动单元格",
|
||||
"usingComponents": {
|
||||
"demo-block": "../../components/demo-block/index",
|
||||
"van-swipe-cell": "../../dist/swipe-cell/index",
|
||||
"van-cell-group": "../../dist/cell-group/index",
|
||||
"van-cell": "../../dist/cell/index",
|
||||
"van-dialog": "../../dist/dialog/index"
|
||||
}
|
||||
}
|
21
example/pages/swipe-cell/index.wxml
Normal file
21
example/pages/swipe-cell/index.wxml
Normal file
@ -0,0 +1,21 @@
|
||||
<demo-block title="基础用法">
|
||||
<van-swipe-cell right-width="{{ 65 }}" left-width="{{ 65 }}">
|
||||
<view slot="left" class="van-swipe-cell__left">选择</view>
|
||||
<van-cell-group>
|
||||
<van-cell title="单元格" value="内容" />
|
||||
</van-cell-group>
|
||||
<view slot="right" class="van-swipe-cell__right">删除</view>
|
||||
</van-swipe-cell>
|
||||
</demo-block>
|
||||
|
||||
<demo-block title="异步关闭">
|
||||
<van-swipe-cell id="swipe-cell" right-width="{{ 65 }}" left-width="{{ 65 }}" async-close bind:close="onClose">
|
||||
<view slot="left" class="van-swipe-cell__left">选择</view>
|
||||
<van-cell-group>
|
||||
<van-cell title="单元格" value="内容" />
|
||||
</van-cell-group>
|
||||
<view slot="right" class="van-swipe-cell__right">删除</view>
|
||||
</van-swipe-cell>
|
||||
</demo-block>
|
||||
|
||||
<van-dialog id="van-dialog" />
|
15
example/pages/swipe-cell/index.wxss
Normal file
15
example/pages/swipe-cell/index.wxss
Normal file
@ -0,0 +1,15 @@
|
||||
.demo-swipe-cell {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.van-swipe-cell__left,
|
||||
.van-swipe-cell__right {
|
||||
display: inline-block;
|
||||
width: 65px;
|
||||
height: 44px;
|
||||
font-size: 15px;
|
||||
line-height: 44px;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
background-color: #f44;
|
||||
}
|
98
packages/swipe-cell/README.md
Normal file
98
packages/swipe-cell/README.md
Normal file
@ -0,0 +1,98 @@
|
||||
## SwipeCell 滑动单元格
|
||||
|
||||
### 使用指南
|
||||
在 index.json 中引入组件
|
||||
```json
|
||||
"usingComponents": {
|
||||
"van-swipe-cell": "path/to/vant-weapp/dist/swipe-cell/index"
|
||||
}
|
||||
```
|
||||
|
||||
### 代码演示
|
||||
|
||||
#### 基础用法
|
||||
|
||||
```html
|
||||
<van-swipe-cell right-width="{{ 65 }}" left-width="{{ 65 }}">
|
||||
<view slot="left">选择</view>
|
||||
<van-cell-group>
|
||||
<van-cell title="单元格" value="内容" />
|
||||
</van-cell-group>
|
||||
<view slot="right">删除</view>
|
||||
</van-swipe-cell>
|
||||
```
|
||||
|
||||
#### 异步关闭
|
||||
|
||||
```html
|
||||
<van-swipe-cell id="swipe-cell" right-width="{{ 65 }}" left-width="{{ 65 }}" async-close bind:close="onClose">
|
||||
<view slot="left">选择</view>
|
||||
<van-cell-group>
|
||||
<van-cell title="单元格" value="内容" />
|
||||
</van-cell-group>
|
||||
<view slot="right">删除</view>
|
||||
</van-swipe-cell>
|
||||
```
|
||||
|
||||
```js
|
||||
export default {
|
||||
methods: {
|
||||
onClose(event) {
|
||||
const { position, instance } = event.detail;
|
||||
switch (position) {
|
||||
case 'left':
|
||||
case 'cell':
|
||||
instance.close();
|
||||
break;
|
||||
case 'right':
|
||||
Dialog.confirm({
|
||||
message: '确定删除吗?'
|
||||
}).then(() => {
|
||||
instance.close();
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### API
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
|------|------|------|------|------|
|
||||
| left-width | 左侧滑动区域宽度 | `Number` | `0` | - |
|
||||
| right-width | 右侧滑动区域宽度 | `Number` | `0` | - |
|
||||
| async-close | 是否异步关闭 | `Boolean` | `false` | - |
|
||||
| disabled | 是否禁用滑动 | `Boolean` | `false` | 1.3.4 |
|
||||
|
||||
### Slot
|
||||
|
||||
| 名称 | 说明 |
|
||||
|------|------|
|
||||
| - | 自定义显示内容 |
|
||||
| left | 左侧滑动内容 |
|
||||
| right | 右侧滑动内容 |
|
||||
|
||||
### Event
|
||||
|
||||
| 事件名 | 说明 | 参数 |
|
||||
|------|------|------|
|
||||
| click | 点击时触发 | 关闭时的点击位置 (`left` `right` `cell` `outside`) |
|
||||
| close | 点击时触发 | 整体是一个 Object,包含 `position`, `instance` 两个 key。 |
|
||||
|
||||
### close 参数
|
||||
|
||||
| 参数 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| position | `String` | 关闭时的点击位置 (`left` `right` `cell` `outside`) |
|
||||
| instance | `Object` | SwipeCell 实例 |
|
||||
|
||||
### 方法
|
||||
|
||||
通过 selectComponent 可以获取到 SwipeCell 实例并调用实例方法
|
||||
|
||||
| 方法名 | 参数 | 返回值 | 介绍 |
|
||||
|------|------|------|------|
|
||||
| open | position: `left | right` | - | 打开单元格侧边栏 |
|
||||
| close | - | - | 收起单元格侧边栏 |
|
3
packages/swipe-cell/index.json
Normal file
3
packages/swipe-cell/index.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"component": true
|
||||
}
|
23
packages/swipe-cell/index.less
Normal file
23
packages/swipe-cell/index.less
Normal file
@ -0,0 +1,23 @@
|
||||
@import '../common/style/var.less';
|
||||
|
||||
.van-swipe-cell {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
&__left,
|
||||
&__right {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
&__left {
|
||||
left: 0;
|
||||
transform: translate3d(-100%, 0, 0);
|
||||
}
|
||||
|
||||
&__right {
|
||||
right: 0;
|
||||
transform: translate3d(100%, 0, 0);
|
||||
}
|
||||
}
|
139
packages/swipe-cell/index.ts
Normal file
139
packages/swipe-cell/index.ts
Normal file
@ -0,0 +1,139 @@
|
||||
import { VantComponent } from '../common/component';
|
||||
import { touch } from '../mixins/touch';
|
||||
|
||||
const THRESHOLD = 0.15;
|
||||
|
||||
VantComponent({
|
||||
props: {
|
||||
disabled: Boolean,
|
||||
leftWidth: {
|
||||
type: Number,
|
||||
value: 0
|
||||
},
|
||||
rightWidth: {
|
||||
type: Number,
|
||||
value: 0
|
||||
},
|
||||
asyncClose: Boolean
|
||||
},
|
||||
|
||||
mixins: [touch],
|
||||
|
||||
data: {
|
||||
offset: 0,
|
||||
draging: false
|
||||
},
|
||||
|
||||
computed: {
|
||||
wrapperStyle() {
|
||||
const { offset, draging } = this.data;
|
||||
return `
|
||||
transform: translate3d(${offset}px, 0, 0);
|
||||
transition: ${draging ? 'none' : '.6s cubic-bezier(0.18, 0.89, 0.32, 1)'};
|
||||
`;
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
onTransitionend() {
|
||||
this.swipe = false;
|
||||
},
|
||||
|
||||
open(position) {
|
||||
const { leftWidth, rightWidth } = this.data;
|
||||
const offset = position === 'left' ? leftWidth : -rightWidth;
|
||||
this.swipeMove(offset);
|
||||
this.resetSwipeStatus();
|
||||
},
|
||||
|
||||
close() {
|
||||
this.setData({ offset: 0 });
|
||||
},
|
||||
|
||||
resetSwipeStatus() {
|
||||
this.swiping = false;
|
||||
this.opened = true;
|
||||
},
|
||||
|
||||
swipeMove(offset = 0) {
|
||||
this.setData({ offset });
|
||||
offset && (this.swiping = true);
|
||||
!offset && (this.opened = false);
|
||||
},
|
||||
|
||||
swipeLeaveTransition(direction) {
|
||||
const { offset, leftWidth, rightWidth } = this.data;
|
||||
const threshold = this.opened ? 1 - THRESHOLD : THRESHOLD;
|
||||
|
||||
// right
|
||||
if (direction > 0 && -offset > rightWidth * threshold && rightWidth > 0) {
|
||||
this.open('right');
|
||||
// left
|
||||
} else if (direction < 0 && offset > leftWidth * threshold && leftWidth > 0) {
|
||||
this.open('left');
|
||||
} else {
|
||||
this.swipeMove();
|
||||
}
|
||||
},
|
||||
|
||||
startDrag(event) {
|
||||
if (this.data.disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setData({ draging: true });
|
||||
this.touchStart(event);
|
||||
|
||||
if (this.opened) {
|
||||
this.startX -= this.data.offset;
|
||||
}
|
||||
},
|
||||
|
||||
onDrag(event) {
|
||||
if (this.data.disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.touchMove(event);
|
||||
const { deltaX } = this;
|
||||
const { leftWidth, rightWidth } = this.data;
|
||||
|
||||
if (
|
||||
(deltaX < 0 && (-deltaX > rightWidth || !rightWidth)) ||
|
||||
(deltaX > 0 && (deltaX > leftWidth || (deltaX > 0 && !leftWidth)))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.direction === 'horizontal') {
|
||||
this.swipeMove(deltaX);
|
||||
}
|
||||
},
|
||||
|
||||
endDrag() {
|
||||
if (this.data.disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setData({ draging: false });
|
||||
if (this.swiping) {
|
||||
this.swipeLeaveTransition(this.data.offset > 0 ? -1 : 1);
|
||||
}
|
||||
},
|
||||
|
||||
onClick(event) {
|
||||
const { key: position = 'outside' } = event.currentTarget.dataset;
|
||||
this.$emit('click', position);
|
||||
|
||||
if (!this.data.offset) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.data.asyncClose) {
|
||||
this.$emit('close', { position, instance: this });
|
||||
} else {
|
||||
this.swipeMove(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
22
packages/swipe-cell/index.wxml
Normal file
22
packages/swipe-cell/index.wxml
Normal file
@ -0,0 +1,22 @@
|
||||
<view
|
||||
class="van-swipe-cell"
|
||||
data-key="cell"
|
||||
bindtap="onClick"
|
||||
bindtouchstart="startDrag"
|
||||
bindtouchmove="onDrag"
|
||||
bindtouchend="endDrag"
|
||||
bindtouchcancel="endDrag"
|
||||
>
|
||||
<view
|
||||
style="{{ wrapperStyle }}"
|
||||
bindtransitionend="onTransitionend"
|
||||
>
|
||||
<view wx:if="{{ leftWidth }}" class="van-swipe-cell__left" data-key="left" catch:tap="onClick">
|
||||
<slot name="left" />
|
||||
</view>
|
||||
<slot />
|
||||
<view wx:if="{{ rightWidth }}" class="van-swipe-cell__right" data-key="right" catch:tap="onClick">
|
||||
<slot name="right" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
Loading…
x
Reference in New Issue
Block a user