Commit 1027838c91903997478e19fb40cbd27a891e8d11

Authored by 刘汉宸
1 parent fe2e253f
Exists in master

perf: 分离hover-class逻辑

packages/button/index.vue
@@ -6,9 +6,11 @@ @@ -6,9 +6,11 @@
6 6
7 <script> 7 <script>
8 import color from 'color'; 8 import color from 'color';
  9 +import BUTTON_MIXIN from '../mixins/button';
9 10
10 export default { 11 export default {
11 name: 'Button', 12 name: 'Button',
  13 + mixins: [BUTTON_MIXIN],
12 props: { 14 props: {
13 type: { 15 type: {
14 type: String, 16 type: String,
@@ -27,31 +29,14 @@ export default { @@ -27,31 +29,14 @@ export default {
27 disabled: Boolean, 29 disabled: Boolean,
28 theme: String, 30 theme: String,
29 color: String, 31 color: String,
30 - hoverClass: {  
31 - type: String,  
32 - default: 'button-hover',  
33 - },  
34 - hoverStartTime: {  
35 - type: Number,  
36 - default: 0,  
37 - },  
38 - hoverStayTime: {  
39 - type: Number,  
40 - default: 70,  
41 - },  
42 - },  
43 - data() {  
44 - return {  
45 - active: false,  
46 - };  
47 }, 32 },
48 computed: { 33 computed: {
49 classRender() { 34 classRender() {
50 return { 35 return {
  36 + ...this.bindClass,
51 [this.size]: true, 37 [this.size]: true,
52 [this.type]: true, 38 [this.type]: true,
53 [this.theme]: !!this.theme, 39 [this.theme]: !!this.theme,
54 - [this.hoverClass]: this.active,  
55 disabled: this.disabled, 40 disabled: this.disabled,
56 block: this.block, 41 block: this.block,
57 round: this.round, 42 round: this.round,
@@ -63,63 +48,34 @@ export default { @@ -63,63 +48,34 @@ export default {
63 if (this.color) { 48 if (this.color) {
64 if (this.type === 'primary') { 49 if (this.type === 'primary') {
65 return { 50 return {
66 - backgroundColor: this.active ? color(this.color).lighten(0.2) : this.color,  
67 - borderColor: this.active ? color(this.color).lighten(0.2) : this.color, 51 + backgroundColor: this.hover ? color(this.color).lighten(0.2) : this.color,
  52 + borderColor: this.hover ? color(this.color).lighten(0.2) : this.color,
68 }; 53 };
69 } else if (this.type === 'secondary') { 54 } else if (this.type === 'secondary') {
70 return { 55 return {
71 - backgroundColor: this.active ? color(this.color).lightness(90) : color(this.color).lightness(95), 56 + backgroundColor: this.hover ? color(this.color).lightness(90) : color(this.color).lightness(95),
72 color: this.color, 57 color: this.color,
73 }; 58 };
74 } else if (this.type === 'plain') { 59 } else if (this.type === 'plain') {
75 return { 60 return {
76 borderColor: this.color, 61 borderColor: this.color,
77 color: this.color, 62 color: this.color,
78 - backgroundColor: this.active ? color(this.color).lightness(90) : color(this.color).lightness(95), 63 + backgroundColor: this.hover ? color(this.color).lightness(90) : color(this.color).lightness(95),
79 }; 64 };
80 } else if (this.type === 'ghost') { 65 } else if (this.type === 'ghost') {
81 return { 66 return {
82 borderColor: this.color, 67 borderColor: this.color,
83 color: this.color, 68 color: this.color,
84 - backgroundColor: this.active ? color(this.color).lightness(95) : undefined, 69 + backgroundColor: this.hover ? color(this.color).lightness(95) : undefined,
85 }; 70 };
86 } else { 71 } else {
87 return { 72 return {
88 - color: this.active ? color(this.color).lighten(0.2) : this.color, 73 + color: this.hover ? color(this.color).lighten(0.2) : this.color,
89 }; 74 };
90 } 75 }
91 } 76 }
92 return {}; 77 return {};
93 }, 78 },
94 - bindEvents() {  
95 - const events = this.$listeners || {};  
96 - const activeEvents = ['mousedown', 'touchstart'];  
97 - const deactiveEvents = ['mouseup', 'mousemove', 'touchend', 'touchmove'];  
98 - let safeEvents = { ...events };  
99 - activeEvents.forEach(key => {  
100 - safeEvents[key] = e => {  
101 - const originEvent = events[key];  
102 - originEvent && originEvent(e);  
103 - if (this.hoverStartTime) {  
104 - setTimeout(() => {  
105 - this.active = true;  
106 - }, this.hoverStartTime);  
107 - } else {  
108 - this.active = true;  
109 - }  
110 - };  
111 - });  
112 - deactiveEvents.forEach(key => {  
113 - safeEvents[key] = e => {  
114 - const originEvent = events[key];  
115 - originEvent && originEvent(e);  
116 - setTimeout(() => {  
117 - this.active = false;  
118 - }, this.hoverStayTime);  
119 - };  
120 - });  
121 - return safeEvents;  
122 - },  
123 }, 79 },
124 }; 80 };
125 </script> 81 </script>
packages/mixins/button.js 0 → 100644
@@ -0,0 +1,66 @@ @@ -0,0 +1,66 @@
  1 +/**
  2 + * @file 仿微信小程序按钮hover-class
  3 + */
  4 +
  5 +export default {
  6 + props: {
  7 + // 指定按钮按下去的样式类。当 hover-class="none" 时,没有点击态效果
  8 + hoverClass: {
  9 + type: String,
  10 + default: 'button-hover',
  11 + },
  12 + // 按住后多久出现点击态,单位毫秒
  13 + hoverStartTime: {
  14 + type: Number,
  15 + default: 0,
  16 + },
  17 + // 手指松开后点击态保留时间,单位毫秒
  18 + hoverStayTime: {
  19 + type: Number,
  20 + default: 70,
  21 + },
  22 + },
  23 + data() {
  24 + return {
  25 + hover: false,
  26 + };
  27 + },
  28 + computed: {
  29 + // 计算绑定的class对象
  30 + bindClass() {
  31 + return {
  32 + [this.hoverClass]: this.hover,
  33 + };
  34 + },
  35 + // 事件hack
  36 + bindEvents() {
  37 + const events = this.$listeners || {};
  38 + const activeEvents = ['mousedown', 'touchstart'];
  39 + const deactiveEvents = ['mouseup', 'mouseout', 'touchend'];
  40 + let safeEvents = { ...events };
  41 + activeEvents.forEach(key => {
  42 + safeEvents[key] = e => {
  43 + const originEvent = events[key];
  44 + originEvent && originEvent(e);
  45 + if (this.hoverStartTime) {
  46 + setTimeout(() => {
  47 + this.hover = true;
  48 + }, this.hoverStartTime);
  49 + } else {
  50 + this.hover = true;
  51 + }
  52 + };
  53 + });
  54 + deactiveEvents.forEach(key => {
  55 + safeEvents[key] = e => {
  56 + const originEvent = events[key];
  57 + originEvent && originEvent(e);
  58 + setTimeout(() => {
  59 + this.hover = false;
  60 + }, this.hoverStayTime);
  61 + };
  62 + });
  63 + return safeEvents;
  64 + },
  65 + },
  66 +};