Sanakey
2021-01-31 53cc6f817625897935fb10c3845ad7be400f3036
提交 | 用户 | age
d98d05 1 import { VantComponent } from '../common/component';
S 2 import { touch } from '../mixins/touch';
3 import { range } from '../common/utils';
4 const THRESHOLD = 0.3;
5 let ARRAY = [];
6 VantComponent({
7   props: {
8     disabled: Boolean,
9     leftWidth: {
10       type: Number,
11       value: 0,
12       observer(leftWidth = 0) {
13         if (this.offset > 0) {
14           this.swipeMove(leftWidth);
15         }
16       },
17     },
18     rightWidth: {
19       type: Number,
20       value: 0,
21       observer(rightWidth = 0) {
22         if (this.offset < 0) {
23           this.swipeMove(-rightWidth);
24         }
25       },
26     },
27     asyncClose: Boolean,
28     name: {
53cc6f 29       type: null,
d98d05 30       value: '',
S 31     },
32   },
33   mixins: [touch],
34   data: {
35     catchMove: false,
53cc6f 36     wrapperStyle: '',
d98d05 37   },
S 38   created() {
39     this.offset = 0;
40     ARRAY.push(this);
41   },
42   destroyed() {
43     ARRAY = ARRAY.filter((item) => item !== this);
44   },
45   methods: {
46     open(position) {
47       const { leftWidth, rightWidth } = this.data;
48       const offset = position === 'left' ? leftWidth : -rightWidth;
49       this.swipeMove(offset);
50       this.$emit('open', {
51         position,
52         name: this.data.name,
53       });
54     },
55     close() {
56       this.swipeMove(0);
57     },
58     swipeMove(offset = 0) {
59       this.offset = range(offset, -this.data.rightWidth, this.data.leftWidth);
60       const transform = `translate3d(${this.offset}px, 0, 0)`;
61       const transition = this.dragging
62         ? 'none'
63         : 'transform .6s cubic-bezier(0.18, 0.89, 0.32, 1)';
64       this.setData({
65         wrapperStyle: `
66         -webkit-transform: ${transform};
67         -webkit-transition: ${transition};
68         transform: ${transform};
69         transition: ${transition};
70       `,
71       });
72     },
73     swipeLeaveTransition() {
74       const { leftWidth, rightWidth } = this.data;
75       const { offset } = this;
76       if (rightWidth > 0 && -offset > rightWidth * THRESHOLD) {
77         this.open('right');
78       } else if (leftWidth > 0 && offset > leftWidth * THRESHOLD) {
79         this.open('left');
80       } else {
81         this.swipeMove(0);
82       }
83       this.setData({ catchMove: false });
84     },
85     startDrag(event) {
86       if (this.data.disabled) {
87         return;
88       }
89       this.startOffset = this.offset;
90       this.touchStart(event);
91     },
92     noop() {},
93     onDrag(event) {
94       if (this.data.disabled) {
95         return;
96       }
97       this.touchMove(event);
98       if (this.direction !== 'horizontal') {
99         return;
100       }
101       this.dragging = true;
53cc6f 102       ARRAY.filter(
S 103         (item) => item !== this && item.offset !== 0
104       ).forEach((item) => item.close());
d98d05 105       this.setData({ catchMove: true });
S 106       this.swipeMove(this.startOffset + this.deltaX);
107     },
108     endDrag() {
109       if (this.data.disabled) {
110         return;
111       }
112       this.dragging = false;
113       this.swipeLeaveTransition();
114     },
115     onClick(event) {
116       const { key: position = 'outside' } = event.currentTarget.dataset;
117       this.$emit('click', position);
118       if (!this.offset) {
119         return;
120       }
121       if (this.data.asyncClose) {
122         this.$emit('close', {
123           position,
124           instance: this,
125           name: this.data.name,
126         });
127       } else {
128         this.swipeMove(0);
129       }
130     },
131   },
132 });