VCollaps.vue 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. <script setup lang="ts">
  2. import { ref, onMounted } from 'vue';
  3. const active=ref(false);
  4. const props=defineProps({
  5. selected: Boolean,
  6. name: String
  7. });
  8. const emit = defineEmits(['collapse-open']);
  9. onMounted(() => {
  10. active.value = props.selected
  11. if (active.value) {
  12. emit('collapse-open')
  13. }
  14. });
  15. function toggle () {
  16. active.value=!active.value;
  17. if (active.value) {
  18. emit('collapse-open')
  19. }
  20. }
  21. </script>
  22. <template>
  23. <div class="card" >
  24. <div class="card-body">
  25. <div class="d-flex justify-content-between align-items-center" @click.prevent="toggle">
  26. <h5 class="card-title">{{ props.name }}</h5>
  27. <div class="collapse-header" :class="{ 'is-active': active }"></div>
  28. </div>
  29. <Transition name="fade">
  30. <div class="collapse-content" v-show="active">
  31. <div class="collapse-content-box">
  32. <slot></slot>
  33. </div>
  34. </div>
  35. </Transition>
  36. </div>
  37. </div>
  38. </template>
  39. <style scoped>
  40. .card-title {
  41. display: flex;
  42. }
  43. .collapse-header {
  44. display: flex;
  45. content: url('../assets/arrow-down.svg');
  46. transform: rotate(-90deg);
  47. }
  48. .is-active {
  49. transform: rotate(0deg);
  50. }
  51. .fade-enter-active,
  52. .fade-leave-active {
  53. transition: opacity 0.2s ease;
  54. }
  55. .fade-enter-from,
  56. .fade-leave-to {
  57. opacity: 0
  58. }
  59. </style>