mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
[Improvement] Collapse: add transition animation (#1500)
This commit is contained in:
parent
a99e73e07e
commit
9da3e0ce5a
@ -8,15 +8,18 @@
|
||||
<cell :class="b('title')" is-link @click="onClick">
|
||||
<slot name="title">{{ title }}</slot>
|
||||
</cell>
|
||||
<div v-show="expanded" :class="b('content')">
|
||||
<slot />
|
||||
<div v-show="show" ref="wrapper" :class="b('wrapper')" @transitionend="onTransitionEnd">
|
||||
<div ref="content" :class="b('content')">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import findParent from '../mixins/find-parent';
|
||||
import { raf } from '../utils/raf';
|
||||
import create from '../utils/create';
|
||||
import findParent from '../mixins/find-parent';
|
||||
|
||||
export default create({
|
||||
name: 'collapse-item',
|
||||
@ -28,6 +31,12 @@ export default create({
|
||||
title: String
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
show: null
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
items() {
|
||||
return this.parent.items;
|
||||
@ -42,6 +51,10 @@ export default create({
|
||||
},
|
||||
|
||||
expanded() {
|
||||
if (!this.parent) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { value } = this.parent;
|
||||
return this.parent.accordion
|
||||
? value === this.currentName
|
||||
@ -52,17 +65,52 @@ export default create({
|
||||
created() {
|
||||
this.findParent('van-collapse');
|
||||
this.items.push(this);
|
||||
this.show = this.expanded;
|
||||
},
|
||||
|
||||
destroyed() {
|
||||
this.items.splice(this.index, 1);
|
||||
},
|
||||
|
||||
watch: {
|
||||
expanded(expanded, prev) {
|
||||
if (prev === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (expanded) {
|
||||
this.show = true;
|
||||
}
|
||||
|
||||
this.$nextTick(() => {
|
||||
const { content, wrapper } = this.$refs;
|
||||
if (!content || !wrapper) {
|
||||
return;
|
||||
}
|
||||
|
||||
const contentHeight = content.clientHeight + 'px';
|
||||
wrapper.style.height = expanded ? 0 : contentHeight;
|
||||
raf(() => {
|
||||
wrapper.style.height = expanded ? contentHeight : 0;
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
onClick() {
|
||||
const { parent } = this;
|
||||
const name = parent.accordion && this.currentName === parent.value ? '' : this.currentName;
|
||||
this.parent.switch(name, !this.expanded);
|
||||
const expanded = !this.expanded;
|
||||
this.parent.switch(name, expanded);
|
||||
},
|
||||
|
||||
onTransitionEnd() {
|
||||
if (!this.expanded) {
|
||||
this.show = false;
|
||||
} else {
|
||||
this.$refs.wrapper.style.height = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -13,7 +13,9 @@ exports[`renders demo correctly 1`] = `
|
||||
<!---->
|
||||
</i>
|
||||
</div>
|
||||
<div class="van-collapse-item__content">提供多样店铺模板,快速搭建网上商城</div>
|
||||
<div class="van-collapse-item__wrapper">
|
||||
<div class="van-collapse-item__content">提供多样店铺模板,快速搭建网上商城</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="van-collapse-item van-hairline--top">
|
||||
<div class="van-cell van-cell--clickable van-hairline van-collapse-item__title">
|
||||
@ -24,7 +26,9 @@ exports[`renders demo correctly 1`] = `
|
||||
<!---->
|
||||
</i>
|
||||
</div>
|
||||
<div class="van-collapse-item__content" style="display:none;">网店吸粉获客、会员分层营销、一机多种收款,告别经营低效和客户流失</div>
|
||||
<div class="van-collapse-item__wrapper" style="display:none;">
|
||||
<div class="van-collapse-item__content">网店吸粉获客、会员分层营销、一机多种收款,告别经营低效和客户流失</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="van-collapse-item van-hairline--top">
|
||||
<div class="van-cell van-cell--clickable van-hairline van-collapse-item__title">
|
||||
@ -35,7 +39,9 @@ exports[`renders demo correctly 1`] = `
|
||||
<!---->
|
||||
</i>
|
||||
</div>
|
||||
<div class="van-collapse-item__content" style="display:none;">线上拓客,随时预约,贴心顺手的开单收银</div>
|
||||
<div class="van-collapse-item__wrapper" style="display:none;">
|
||||
<div class="van-collapse-item__content">线上拓客,随时预约,贴心顺手的开单收银</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -50,7 +56,9 @@ exports[`renders demo correctly 1`] = `
|
||||
<!---->
|
||||
</i>
|
||||
</div>
|
||||
<div class="van-collapse-item__content">提供多样店铺模板,快速搭建网上商城</div>
|
||||
<div class="van-collapse-item__wrapper">
|
||||
<div class="van-collapse-item__content">提供多样店铺模板,快速搭建网上商城</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="van-collapse-item van-hairline--top">
|
||||
<div class="van-cell van-cell--clickable van-hairline van-collapse-item__title">
|
||||
@ -61,7 +69,9 @@ exports[`renders demo correctly 1`] = `
|
||||
<!---->
|
||||
</i>
|
||||
</div>
|
||||
<div class="van-collapse-item__content" style="display:none;">网店吸粉获客、会员分层营销、一机多种收款,告别经营低效和客户流失</div>
|
||||
<div class="van-collapse-item__wrapper" style="display:none;">
|
||||
<div class="van-collapse-item__content">网店吸粉获客、会员分层营销、一机多种收款,告别经营低效和客户流失</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="van-collapse-item van-hairline--top">
|
||||
<div class="van-cell van-cell--clickable van-hairline van-collapse-item__title">
|
||||
@ -72,7 +82,9 @@ exports[`renders demo correctly 1`] = `
|
||||
<!---->
|
||||
</i>
|
||||
</div>
|
||||
<div class="van-collapse-item__content" style="display:none;">线上拓客,随时预约,贴心顺手的开单收银</div>
|
||||
<div class="van-collapse-item__wrapper" style="display:none;">
|
||||
<div class="van-collapse-item__content">线上拓客,随时预约,贴心顺手的开单收银</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -93,8 +105,10 @@ exports[`renders demo correctly 1`] = `
|
||||
<!---->
|
||||
</i>
|
||||
</div>
|
||||
<div class="van-collapse-item__content" style="display:none;">
|
||||
提供多样店铺模板,快速搭建网上商城
|
||||
<div class="van-collapse-item__wrapper" style="display:none;">
|
||||
<div class="van-collapse-item__content">
|
||||
提供多样店铺模板,快速搭建网上商城
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="van-collapse-item van-hairline--top">
|
||||
@ -106,7 +120,9 @@ exports[`renders demo correctly 1`] = `
|
||||
<!---->
|
||||
</i>
|
||||
</div>
|
||||
<div class="van-collapse-item__content" style="display:none;">网店吸粉获客、会员分层营销、一机多种收款,告别经营低效和客户流失</div>
|
||||
<div class="van-collapse-item__wrapper" style="display:none;">
|
||||
<div class="van-collapse-item__content">网店吸粉获客、会员分层营销、一机多种收款,告别经营低效和客户流失</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,6 +1,6 @@
|
||||
import Collapse from '..';
|
||||
import CollapseItem from '../../collapse-item';
|
||||
import { mount } from '../../../test/utils';
|
||||
import { later, mount } from '../../../test/utils';
|
||||
|
||||
const component = {
|
||||
template: `
|
||||
@ -24,7 +24,7 @@ const component = {
|
||||
}
|
||||
};
|
||||
|
||||
test('basic mode', () => {
|
||||
test('basic mode', async() => {
|
||||
const wrapper = mount(component);
|
||||
|
||||
const titles = wrapper.findAll('.van-collapse-item__title');
|
||||
@ -34,13 +34,14 @@ test('basic mode', () => {
|
||||
titles.at(1).trigger('click');
|
||||
expect(wrapper.vm.active).toEqual(['first', 1]);
|
||||
|
||||
await later();
|
||||
titles.at(0).trigger('click');
|
||||
expect(wrapper.vm.active).toEqual([1]);
|
||||
|
||||
wrapper.destroy();
|
||||
});
|
||||
|
||||
it('accordion', () => {
|
||||
it('accordion', async() => {
|
||||
const wrapper = mount(component, {
|
||||
propsData: {
|
||||
accordion: true
|
||||
@ -54,6 +55,7 @@ it('accordion', () => {
|
||||
titles.at(1).trigger('click');
|
||||
expect(wrapper.vm.active).toEqual(1);
|
||||
|
||||
await later();
|
||||
titles.at(0).trigger('click');
|
||||
expect(wrapper.vm.active).toEqual('first');
|
||||
|
||||
|
@ -12,6 +12,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
&__wrapper {
|
||||
overflow: hidden;
|
||||
will-change: height;
|
||||
transition: height .3s ease-in-out;
|
||||
}
|
||||
|
||||
&__content {
|
||||
padding: 15px;
|
||||
background-color: #fff;
|
||||
|
Loading…
x
Reference in New Issue
Block a user