Blame view

src/wxcomponents/vant/mixins/transition.js 4.22 KB
289f85d9e   Adam   提交
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
  import { isObj } from '../common/utils';
  const getClassNames = (name) => ({
      enter: `van-${name}-enter van-${name}-enter-active enter-class enter-active-class`,
      'enter-to': `van-${name}-enter-to van-${name}-enter-active enter-to-class enter-active-class`,
      leave: `van-${name}-leave van-${name}-leave-active leave-class leave-active-class`,
      'leave-to': `van-${name}-leave-to van-${name}-leave-active leave-to-class leave-active-class`
  });
  const nextTick = () => new Promise(resolve => setTimeout(resolve, 1000 / 30));
  export const transition = function (showDefaultValue) {
      return Behavior({
          properties: {
              customStyle: String,
              // @ts-ignore
              show: {
                  type: Boolean,
                  value: showDefaultValue,
                  observer: 'observeShow'
              },
              // @ts-ignore
              duration: {
                  type: null,
                  value: 300,
                  observer: 'observeDuration'
              },
              name: {
                  type: String,
                  value: 'fade'
              }
          },
          data: {
              type: '',
              inited: false,
              display: false
          },
          attached() {
              if (this.data.show) {
                  this.enter();
              }
          },
          methods: {
              observeShow(value) {
                  value ? this.enter() : this.leave();
              },
              enter() {
                  const { duration, name } = this.data;
                  const classNames = getClassNames(name);
                  const currentDuration = isObj(duration) ? duration.enter : duration;
                  this.status = 'enter';
                  this.$emit('before-enter');
                  Promise.resolve()
                      .then(nextTick)
                      .then(() => {
                      this.checkStatus('enter');
                      this.$emit('enter');
                      this.setData({
                          inited: true,
                          display: true,
                          classes: classNames.enter,
                          currentDuration
                      });
                  })
                      .then(nextTick)
                      .then(() => {
                      this.checkStatus('enter');
                      this.transitionEnded = false;
                      this.setData({
                          classes: classNames['enter-to']
                      });
                  })
                      .catch(() => { });
              },
              leave() {
                  if (!this.data.display) {
                      return;
                  }
                  const { duration, name } = this.data;
                  const classNames = getClassNames(name);
                  const currentDuration = isObj(duration) ? duration.leave : duration;
                  this.status = 'leave';
                  this.$emit('before-leave');
                  Promise.resolve()
                      .then(nextTick)
                      .then(() => {
                      this.checkStatus('leave');
                      this.$emit('leave');
                      this.setData({
                          classes: classNames.leave,
                          currentDuration
                      });
                  })
                      .then(nextTick)
                      .then(() => {
                      this.checkStatus('leave');
                      this.transitionEnded = false;
                      setTimeout(() => this.onTransitionEnd(), currentDuration);
                      this.setData({
                          classes: classNames['leave-to']
                      });
                  })
                      .catch(() => { });
              },
              checkStatus(status) {
                  if (status !== this.status) {
                      throw new Error(`incongruent status: ${status}`);
                  }
              },
              onTransitionEnd() {
                  if (this.transitionEnded) {
                      return;
                  }
                  this.transitionEnded = true;
                  this.$emit(`after-${this.status}`);
                  const { show, display } = this.data;
                  if (!show && display) {
                      this.setData({ display: false });
                  }
              }
          }
      });
  };