fs-sidebar.vue 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. <template>
  2. <view class="fs-side-bar">
  3. <view class="fs-side-bar-left" :style="{ width: width }">
  4. <view
  5. class="fs-side-bar-item line1"
  6. :class="{ 'fs-side-bar-active': activeId ? activeId === item[valueKey] : index === 0 }"
  7. v-for="(item, index) in list"
  8. :key="item[valueKey]"
  9. @click="handleClick(item, index)"
  10. >
  11. {{ item[titleKey] }}
  12. </view>
  13. </view>
  14. <view class="fs-side-bar-right"><slot></slot></view>
  15. </view>
  16. </template>
  17. <script>
  18. /**
  19. * 侧边栏组件
  20. * @description 侧边栏组件
  21. * @property {Array} list sidebar列表
  22. * @property {String} value 默认激活项的value(通常为id)
  23. * @property {String} valueKey 激活项value的key
  24. * @property {String} titleKey 显示内容的key
  25. * @property {String} width 侧边栏组宽度
  26. * @event {Function} change 激活项变化事件
  27. */
  28. export default {
  29. name: 'fs-sidebar'
  30. }
  31. </script>
  32. <script setup>
  33. import { ref } from 'vue'
  34. const props = defineProps({
  35. list: {
  36. type: Array,
  37. default() {
  38. return []
  39. }
  40. },
  41. value: null,
  42. valueKey: {
  43. type: String,
  44. default: 'id'
  45. },
  46. titleKey: {
  47. type: String,
  48. default: 'title'
  49. },
  50. width: {
  51. type: String,
  52. default: '210rpx'
  53. }
  54. })
  55. const emits = defineEmits(['change'])
  56. const activeId = ref(props.value)
  57. const handleClick = (item, index) => {
  58. activeId.value = item[props.valueKey]
  59. emits('change', {
  60. item,
  61. index
  62. })
  63. }
  64. </script>
  65. <style lang="scss" scoped>
  66. .fs-side-bar {
  67. display: flex;
  68. height: 100%;
  69. &-left {
  70. flex-shrink: 0;
  71. background-color: #fafafa;
  72. overflow: auto;
  73. }
  74. &-item {
  75. padding: 30rpx var(--gutter);
  76. position: relative;
  77. }
  78. &-active {
  79. background-color: #fff;
  80. color: var(--primary);
  81. &::before {
  82. position: absolute;
  83. content: '';
  84. left: 0;
  85. top: 0;
  86. height: 100%;
  87. width: 6rpx;
  88. background-color: currentColor;
  89. }
  90. }
  91. &-right {
  92. flex: 1;
  93. background-color: #fff;
  94. overflow: auto;
  95. }
  96. }
  97. </style>