index.vue 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. <template>
  2. <div class="toolbar">
  3. <div class="tabs">
  4. <div
  5. class="tab"
  6. :class="{ 'active': tab.value === toolbarState }"
  7. v-for="tab in currentTabs"
  8. :key="tab.value"
  9. @click="setToolbarState(tab.value)"
  10. >{{tab.label}}</div>
  11. </div>
  12. <div class="content">
  13. <component :is="currentPanelComponent"></component>
  14. </div>
  15. </div>
  16. </template>
  17. <script lang="ts">
  18. import { computed, defineComponent, watch } from 'vue'
  19. import { useStore } from 'vuex'
  20. import { MutationTypes, State } from '@/store'
  21. import { ToolbarState, ToolbarStates } from '@/types/toolbar'
  22. import ElementStylePanel from './ElementStylePanel/index.vue'
  23. import ElementPositionPanel from './ElementPositionPanel.vue'
  24. import ElementAnimationPanel from './ElementAnimationPanel.vue'
  25. import SlideStylePanel from './SlideStylePanel.vue'
  26. import SlideAnimationPanel from './SlideAnimationPanel.vue'
  27. import MultiPositionPanel from './MultiPositionPanel.vue'
  28. export default defineComponent({
  29. name: 'toolbar',
  30. setup() {
  31. const store = useStore<State>()
  32. const toolbarState = computed(() => store.state.toolbarState)
  33. const elementTabs = [
  34. { label: '样式', value: ToolbarStates.EL_STYLE },
  35. { label: '位置', value: ToolbarStates.EL_POSITION },
  36. { label: '动画', value: ToolbarStates.EL_ANIMATION },
  37. ]
  38. const slideTabs = [
  39. { label: '页面样式', value: ToolbarStates.SLIDE_STYLE },
  40. { label: '翻页动画', value: ToolbarStates.SLIDE_ANIMATION },
  41. ]
  42. const multiSelectTabs = [
  43. { label: '位置', value: ToolbarStates.MULTI_POSITION },
  44. { label: '样式', value: ToolbarStates.EL_STYLE },
  45. ]
  46. const setToolbarState = (value: ToolbarState) => {
  47. store.commit(MutationTypes.SET_TOOLBAR_STATE, value)
  48. }
  49. const activeElementIdList = computed(() => store.state.activeElementIdList)
  50. const currentTabs = computed(() => {
  51. if(!activeElementIdList.value.length) return slideTabs
  52. else if(activeElementIdList.value.length > 1) return multiSelectTabs
  53. return elementTabs
  54. })
  55. watch(currentTabs, () => {
  56. const currentTabsValue = currentTabs.value.map(tab => tab.value)
  57. if(!currentTabsValue.includes(toolbarState.value)) {
  58. store.commit(MutationTypes.SET_TOOLBAR_STATE, currentTabsValue[0])
  59. }
  60. })
  61. const currentPanelComponent = computed(() => {
  62. const panelMap = {
  63. [ToolbarStates.EL_STYLE]: ElementStylePanel,
  64. [ToolbarStates.EL_POSITION]: ElementPositionPanel,
  65. [ToolbarStates.EL_ANIMATION]: ElementAnimationPanel,
  66. [ToolbarStates.SLIDE_STYLE]: SlideStylePanel,
  67. [ToolbarStates.SLIDE_ANIMATION]: SlideAnimationPanel,
  68. [ToolbarStates.MULTI_POSITION]: MultiPositionPanel,
  69. }
  70. return panelMap[toolbarState.value] || null
  71. })
  72. return {
  73. toolbarState,
  74. currentTabs,
  75. setToolbarState,
  76. currentPanelComponent,
  77. }
  78. },
  79. })
  80. </script>
  81. <style lang="scss" scoped>
  82. .toolbar {
  83. border-left: solid 1px $borderColor;
  84. background-color: #fff;
  85. display: flex;
  86. flex-direction: column;
  87. }
  88. .tabs {
  89. height: 40px;
  90. font-size: 12px;
  91. flex-shrink: 0;
  92. display: flex;
  93. }
  94. .tab {
  95. flex: 1;
  96. display: flex;
  97. justify-content: center;
  98. align-items: center;
  99. background-color: $lightGray;
  100. border-bottom: 1px solid $borderColor;
  101. cursor: pointer;
  102. &.active {
  103. background-color: #fff;
  104. border-bottom-color: #fff;
  105. }
  106. & + .tab {
  107. border-left: 1px solid $borderColor;
  108. }
  109. }
  110. .content {
  111. padding: 12px;
  112. font-size: 13px;
  113. overflow: overlay;
  114. }
  115. </style>