Skip to content

Commit 8833c83

Browse files
committed
refactor: rollback Collapse
1 parent b06f0d1 commit 8833c83

File tree

1 file changed

+74
-69
lines changed

1 file changed

+74
-69
lines changed
Lines changed: 74 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,85 @@
1-
<script lang="jsx" setup>
1+
<script lang="jsx">
22
import { addClass, removeClass } from '../../utils/dom.utils';
3-
import { onMounted, ref, watchEffect } from 'vue';
4-
5-
const props = defineProps({
6-
tag: { type: String, default: 'div' },
7-
modelValue: { type: Boolean, default: false },
8-
transition: { type: Number, default: 350 },
9-
});
10-
const emit = defineEmits(['show', 'shown', 'hide', 'hidden']);
113
124
const COLLAPSE = 'collapse';
135
const IN = 'in';
146
const COLLAPSING = 'collapsing';
15-
let timeoutId = 0;
16-
const element = ref(null);
177
18-
function toggle(show) {
19-
clearTimeout(timeoutId);
20-
const el = element.value;
21-
if (!el) {
22-
return;
23-
}
24-
if (show) {
25-
emit('show');
26-
removeClass(el, COLLAPSE);
27-
el.style.height = 'auto';
28-
const height = window.getComputedStyle(el).height;
29-
el.style.height = null;
30-
addClass(el, COLLAPSING);
31-
el.offsetHeight; // force repaint
32-
el.style.height = height;
33-
timeoutId = setTimeout(() => {
34-
removeClass(el, COLLAPSING);
35-
addClass(el, COLLAPSE);
8+
export default {
9+
props: {
10+
tag: {
11+
type: String,
12+
default: 'div',
13+
},
14+
modelValue: {
15+
type: Boolean,
16+
default: false,
17+
},
18+
transition: {
19+
type: Number,
20+
default: 350,
21+
},
22+
},
23+
emits: ['show', 'shown', 'hide', 'hidden'],
24+
data() {
25+
return {
26+
timeoutId: 0,
27+
};
28+
},
29+
watch: {
30+
modelValue(show) {
31+
this.toggle(show);
32+
},
33+
},
34+
mounted() {
35+
const el = this.$el;
36+
addClass(el, COLLAPSE);
37+
if (this.modelValue) {
3638
addClass(el, IN);
37-
el.style.height = null;
38-
timeoutId = 0;
39-
emit('shown');
40-
}, props.transition);
41-
} else {
42-
emit('hide');
43-
el.style.height = window.getComputedStyle(el).height;
44-
removeClass(el, IN);
45-
removeClass(el, COLLAPSE);
46-
el.offsetHeight;
47-
el.style.height = null;
48-
addClass(el, COLLAPSING);
49-
timeoutId = setTimeout(() => {
50-
addClass(el, COLLAPSE);
51-
removeClass(el, COLLAPSING);
52-
el.style.height = null;
53-
timeoutId = 0;
54-
emit('hidden');
55-
}, props.transition);
56-
}
57-
}
58-
59-
watchEffect(() => {
60-
toggle(props.modelValue);
61-
});
62-
63-
onMounted(() => {
64-
addClass(element.value, COLLAPSE);
65-
if (props.modelValue) {
66-
addClass(element.value, IN);
67-
}
68-
});
69-
</script>
70-
71-
<script lang="jsx">
72-
import { defineComponent } from 'vue';
73-
74-
export default defineComponent({
39+
}
40+
},
41+
methods: {
42+
toggle(show) {
43+
clearTimeout(this.timeoutId);
44+
const el = this.$el;
45+
if (show) {
46+
this.$emit('show');
47+
removeClass(el, COLLAPSE);
48+
el.style.height = 'auto';
49+
const height = window.getComputedStyle(el).height;
50+
el.style.height = null;
51+
addClass(el, COLLAPSING);
52+
el.offsetHeight; // force repaint
53+
el.style.height = height;
54+
this.timeoutId = setTimeout(() => {
55+
removeClass(el, COLLAPSING);
56+
addClass(el, COLLAPSE);
57+
addClass(el, IN);
58+
el.style.height = null;
59+
this.timeoutId = 0;
60+
this.$emit('shown');
61+
}, this.transition);
62+
} else {
63+
this.$emit('hide');
64+
el.style.height = window.getComputedStyle(el).height;
65+
removeClass(el, IN);
66+
removeClass(el, COLLAPSE);
67+
el.offsetHeight;
68+
el.style.height = null;
69+
addClass(el, COLLAPSING);
70+
this.timeoutId = setTimeout(() => {
71+
addClass(el, COLLAPSE);
72+
removeClass(el, COLLAPSING);
73+
el.style.height = null;
74+
this.timeoutId = 0;
75+
this.$emit('hidden');
76+
}, this.transition);
77+
}
78+
},
79+
},
7580
render() {
7681
const Tag = this.tag;
77-
return <Tag ref="element">{this.$slots.default?.()}</Tag>;
82+
return <Tag>{this.$slots.default?.()}</Tag>;
7883
},
79-
});
84+
};
8085
</script>

0 commit comments

Comments
 (0)