笔者在2年前曾用jquery写过一个手风琴组件,jquery提供的slideUp、slideDown方法简直就是给手风琴量身定做的,不仅能够获得内容的高度并正确打开,还能加上流畅的动画效果,这里动画效果请小伙伴们自行脑部一下哈~。然而两年后的今天。需要在vue中来做了,笔者是对代码有洁癖的人,不想使用js操作dom获取高度在设置动画,而是要使用vue中的transition标签来实现。最终的效果还是有些瑕疵,希望小伙伴们可以提出建议,来完善一下,前提是不要操作dom哦~,下面直接上代码啦:

<template>
  <!--手风琴组件-->
  <div>
    <ul>
      <li>
        <div class="title" @click="toggle(1)">被收养人信息</div>
        <transition name="slide">
          <div class="content" v-show="show===1">
            <slot name="one"></slot>
          </div>
        </transition>
      </li>
      <li>
        <div class="title" @click="toggle(2)">二条</div>
        <transition name="slide">
          <div class="content" v-show="show===2">
            <slot name="two"></slot>
          </div>
        </transition>
      </li>
      <li>
        <div class="title" @click="toggle(3)">三条</div>
        <transition name="slide">
          <div class="content" v-show="show===3">
            <slot name="three"></slot>
          </div>
        </transition>
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  name: "Alaccordion",
  data() {
    return {
      show: 1
    };
  },
  methods: {
    toggle(index) {
      // 获取index 来判断当前点击并展示
      this.show = index;
    }
  }
};
</script>
<style scoped>
ul {
  list-style: none;
  margin: 0;
  padding: 0;
}
.title {
  height: 50px;
  line-height: 50px;
  border: 1px solid #ddeded;
  cursor: pointer;
}
.content {
  background: black;
  color: #fff;
}
/* 定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。也就是说dom刚渲染所执行的动画。 */
.slide-enter {
  max-height: 0px;
}
/* 定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。 */
.slide-enter-active {
  transition: all 0.5s ease;
}
/*  2.1.8版及以上 定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时 v-enter 被移除),在过渡/动画完成之后移除。 */
.slide-enter-to {
  max-height: 1000px;
}

/* 定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。 */
.slide-leave {
  max-height: 1000px;
}
/* 定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。 */
.slide-leave-active {
  transition: all 0.5s ease;
}
/*  2.1.8版及以上 定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave 被删除),在过渡/动画完成之后移除。 */
.slide-leave-to {
  max-height: 0px;
}
</style>

下面是父组件调用:

<template>
  <!--父组件-->
  <al-accordion>
    <template v-slot:one>
      <div style="height:200px">111</div>
    </template>
    <template v-slot:two>
      <div style="height:500px">222</div>
    </template>
    <template v-slot:three>
      <div style="height:100px">333</div>
    </template>
  </al-accordion>
</template>

<script>
// 如果你想直接拿来用,记得路径要改对哦~
import alAccordion from "../components/Alaccordion.vue";

export default {
  name: "Accordion",
  components: {
    alAccordion
  },
  data() {
    return {};
  },
  methods: {}
};
</script>
<style scoped>
</style>

如果你实践了上面的代码,会发现只有打开动画完成后,关闭动画才会执行,笔者一直没有发现好的解决方法,如果你知道,希望不吝赐教。