index.vue 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. <template>
  2. <transition name="slide">
  3. <div class="panel" v-if="show">
  4. <div class="panel-header">
  5. <h3>{{ nodeDataCpt.title }}</h3>
  6. <button @click="$emit('update:show', false)">×</button>
  7. </div>
  8. <div class="panel-content">
  9. <template v-if="nodeDataCpt.type === 'root'">
  10. <rootPanel :node="node"/>
  11. </template>
  12. <template v-if="nodeDataCpt.type === 'if-else'">
  13. <ifElsePanel :node="node"/>
  14. </template>
  15. </div>
  16. </div>
  17. </transition>
  18. </template>
  19. <script setup lang="ts">
  20. import {computed, getCurrentInstance, reactive, ref} from "vue";
  21. import rootPanel from './root/index.vue'
  22. import ifElsePanel from './is-else/index.vue'
  23. const emits = defineEmits([])
  24. const props = defineProps({
  25. show: {},
  26. node: {}
  27. })
  28. const {proxy}: any = getCurrentInstance()
  29. const state: any = reactive({})
  30. const nodeDataCpt = computed(() => props.node?.data || {})
  31. </script>
  32. <style lang="scss" scoped>
  33. .panel {
  34. position: fixed;
  35. top: 0;
  36. right: 0;
  37. width: 400px;
  38. height: 100%;
  39. background-color: white;
  40. box-shadow: -2px 0 8px rgba(0, 0, 0, 0.15);
  41. z-index: 1000;
  42. display: flex;
  43. flex-direction: column;
  44. .panel-header {
  45. padding: 16px;
  46. border-bottom: 1px solid #eee;
  47. display: flex;
  48. justify-content: space-between;
  49. align-items: center;
  50. }
  51. .panel-content {
  52. padding: 16px;
  53. flex: 1;
  54. overflow-y: auto;
  55. }
  56. }
  57. /* 过渡动画 */
  58. .slide-enter-active,
  59. .slide-leave-active {
  60. transition: transform 0.3s ease;
  61. }
  62. .slide-enter-from,
  63. .slide-leave-to {
  64. transform: translateX(100%);
  65. }
  66. </style>