fs-collapse-item.vue 1.9 KB

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