pane.vue 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. <template>
  2. <ActionMenus
  3. v-if="!store.child.value"
  4. class="menus"
  5. :class="{ level: level === 2 }"
  6. :menus="store.menus as any"
  7. :active-key="store.activeMenuKey.value"
  8. dire="column"
  9. />
  10. <scene-menus
  11. :parentKey="store.activeMenuKey.value"
  12. v-if="store.child.value"
  13. @back="store.child.value = null"
  14. :menus="store.child.value as MenuRaw[]"
  15. :level="level + 1"
  16. />
  17. </template>
  18. <script lang="ts" setup>
  19. import ActionMenus from "@/components/group-button/index.vue";
  20. import { generateMixMenus, MenuRaw, menus, findMenuByKey } from "./menus";
  21. import { joinActions } from "./actions";
  22. import { computed, onMounted, onUnmounted, ref, watchEffect } from "vue";
  23. import { disabledMap, laserModeStack } from "@/hook";
  24. import { Mode } from "@/sdk";
  25. const props = withDefaults(
  26. defineProps<{ menus?: MenuRaw[]; level?: number; parentKey?: string }>(),
  27. { level: 1 }
  28. );
  29. const emit = defineEmits<{
  30. (e: "back"): void;
  31. (e: "enterChild"): void;
  32. (e: "leaveChild"): void;
  33. }>();
  34. const backMenu = {
  35. icon: "return",
  36. text: "",
  37. key: "back",
  38. onClick: () => emit("back"),
  39. };
  40. const menusMix = computed(() => (props.level === 1 ? menus : [backMenu, ...props.menus]));
  41. const store = generateMixMenus("children", (m) => m, menusMix.value);
  42. watchEffect(() => {
  43. const menu = findMenuByKey(store.itemActiveKey.value as any);
  44. if (menu?.disabled && menu?.disabled()) {
  45. store.itemActiveKey.value = null;
  46. }
  47. });
  48. watchEffect((onCleanup) => {
  49. const menu = store.activeMenuKey.value && findMenuByKey(store.activeMenuKey.value);
  50. if (store.child && menu?.onClick) {
  51. const leaveHook = menu.onClick();
  52. leaveHook && onCleanup(leaveHook);
  53. } else {
  54. onCleanup(() => {});
  55. }
  56. });
  57. if (props.level === 1) {
  58. watchEffect(() => {
  59. disabledMap.photo = !store.child.value?.length;
  60. });
  61. watchEffect(() => {
  62. if (store.child.value) {
  63. emit("enterChild");
  64. } else {
  65. emit("leaveChild");
  66. }
  67. });
  68. }
  69. const stopWatch = joinActions(store.itemActiveKey);
  70. onUnmounted(() => {
  71. stopWatch();
  72. if (props.parentKey === "measure") {
  73. laserModeStack.pop();
  74. }
  75. });
  76. onMounted(() => {
  77. if (props.level > 1) {
  78. const defaultMenu = props.menus.find((menu) => {
  79. if (typeof menu.defaultSelect === "function") {
  80. return menu.defaultSelect();
  81. } else {
  82. return menu.defaultSelect;
  83. }
  84. });
  85. console.log(defaultMenu);
  86. store.itemActiveKey.value = defaultMenu?.key;
  87. // store.activeMenuKey.value =
  88. if (props.parentKey === "measure") {
  89. laserModeStack.push(ref(Mode.cloud));
  90. }
  91. }
  92. });
  93. </script>
  94. <script lang="ts">
  95. export default { name: "scene-menus" };
  96. </script>
  97. <style lang="scss" scoped>
  98. .menus {
  99. position: absolute;
  100. left: var(--boundMargin);
  101. top: 50%;
  102. transform: translateY(-50%);
  103. z-index: 2;
  104. }
  105. </style>
  106. <style lang="scss">
  107. .level div:first-child {
  108. background-color: rgba(255, 255, 255, 0.3);
  109. height: 50px;
  110. width: 50px;
  111. min-width: 50px;
  112. border-radius: 50%;
  113. margin-bottom: 30px !important;
  114. position: relative;
  115. i {
  116. font-size: 16px !important;
  117. }
  118. &:after {
  119. position: absolute;
  120. content: "";
  121. height: 1px;
  122. left: 10px;
  123. right: 10px;
  124. bottom: -15px;
  125. background-color: rgba(255, 255, 255, 0.2);
  126. }
  127. }
  128. </style>