index.vue 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. <template>
  2. <ButtonPane class="menus" :size="size" :dire="dire">
  3. <div
  4. v-for="menu in menus"
  5. :key="menu.key"
  6. class="menu"
  7. :style="menuStyle"
  8. :class="{ active: activeKey === menu.key, dire }"
  9. @click="menu.onClick && menu.onClick(menu)"
  10. >
  11. <ui-icon :type="menu.icon || 'close'" class="icon"/>
  12. <p v-if="menu.text">{{ menu.text }}</p>
  13. </div>
  14. </ButtonPane>
  15. </template>
  16. <script setup lang="ts">
  17. import ButtonPane from '@/components/button-pane/index.vue'
  18. import UiIcon from "@/components/base/components/icon/index.vue";
  19. import {computed} from "vue";
  20. type Menu = {
  21. key: any,
  22. text?: string,
  23. icon?: string,
  24. onClick?: (menu: Menu) => void
  25. }
  26. const props = withDefaults(
  27. defineProps<{ menus: Menu[], activeKey?: any, dire?: 'row' | 'column', size?: number }>(),
  28. {dire: 'row', size: 64}
  29. )
  30. const menuStyle = computed(() => {
  31. const offset = props.size / 4;
  32. return props.dire === 'row' ? { marginRight: offset + "px" } : { marginBottom: offset + 'px' }
  33. })
  34. </script>
  35. <style lang="scss" scoped>
  36. .menu {
  37. width: 56px;
  38. display: flex;
  39. flex-direction: column;
  40. cursor: pointer;
  41. height: 100%;
  42. text-align: center;
  43. transition: color .3s ease;
  44. color: #fff;
  45. &.active,
  46. &:hover {
  47. color: var(--colors-primary-base);
  48. }
  49. &.active {
  50. background: rgba(255, 255, 255, 0.1);;
  51. }
  52. .icon {
  53. display: flex;
  54. align-items: center;
  55. justify-content: center;
  56. font-size: 20px;
  57. flex: 1;
  58. }
  59. p {
  60. line-height: 17px;
  61. font-size: 12px;
  62. }
  63. }
  64. </style>