fs-collapse-item.vue 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. <template>
  2. <view class="fs-collapse-item" :class="{ 'fs-collapse-item-border': border }">
  3. <view class="fs-title-box" :class="[{ open }, position]" @click="handleClick">
  4. <view class="fs-item-hd" :class="[highlight]"><slot name="title"></slot></view>
  5. <view class="fs-arrow-box" :class="[{ open }, highlight]">
  6. <slot name="arrow"><view class="fs-arrow"></view></slot>
  7. </view>
  8. </view>
  9. <view class="content" v-if="open"><slot name="content"></slot></view>
  10. </view>
  11. </template>
  12. <script>
  13. /**
  14. * 折叠面板组件
  15. * @description 折叠面板组件
  16. * @property {String, Number} name name
  17. * @property {Boolean} disabled disabled
  18. */
  19. export default {
  20. name: 'fs-collapse-item'
  21. }
  22. </script>
  23. <script setup>
  24. import { computed, inject, watch, ref } from 'vue'
  25. const props = defineProps({
  26. name: [String, Number],
  27. disabled: Boolean
  28. })
  29. const collapse = inject('collapse')
  30. const border = collapse.border
  31. const open = ref(collapse.allOpen || collapse.active === props.name)
  32. const position = collapse.position
  33. const highlight = computed(() => open.value && !props.disabled && collapse.activeType)
  34. const setActive = active => {
  35. open.value = active && !props.disabled
  36. }
  37. collapse.children.push({
  38. name: props.name,
  39. open,
  40. setActive
  41. })
  42. const handleClick = () => {
  43. !props.disabled && collapse.emitEvent(props.name)
  44. }
  45. </script>
  46. <style lang="scss" scoped>
  47. .fs-collapse-item {
  48. &-border {
  49. border-bottom: 1px solid var(--border-color);
  50. }
  51. .open {
  52. .fs-arrow {
  53. transform: rotate(135deg);
  54. }
  55. }
  56. }
  57. .fs-title-box {
  58. display: flex;
  59. padding: 20rpx var(--gutter);
  60. justify-content: space-between;
  61. align-items: center;
  62. .fs-item-hd {
  63. min-width: 0;
  64. flex: 1;
  65. }
  66. &.left {
  67. flex-direction: row-reverse;
  68. .fs-item-hd {
  69. padding-left: 10rpx;
  70. }
  71. }
  72. &.right {
  73. .fs-item-hd {
  74. padding-right: 10rpx;
  75. }
  76. }
  77. }
  78. .fs-arrow-box {
  79. line-height: 1;
  80. }
  81. .fs-arrow {
  82. border-top: 2rpx solid currentColor;
  83. border-right: 2rpx solid currentColor;
  84. transform: rotate(45deg);
  85. width: 16rpx;
  86. height: 16rpx;
  87. color: inherit;
  88. transition: all 0.1s;
  89. flex-shrink: 0;
  90. }
  91. </style>