vp-example.vue 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. <script setup lang="ts">
  2. import { computed, unref, watchEffect } from 'vue'
  3. import { File, Repl, ReplStore } from '@vue/repl'
  4. import mainCode from './main.vue?raw'
  5. import deptCode from './dept?raw'
  6. import { loadKanKanThemeChalkStyle } from './dept'
  7. import type { SFCOptions } from '@vue/repl'
  8. const sfcOptions: SFCOptions = {
  9. script: {
  10. reactivityTransform: true,
  11. },
  12. }
  13. const props = defineProps({
  14. file: {
  15. type: String,
  16. required: true,
  17. },
  18. raw: {
  19. type: String,
  20. required: true,
  21. },
  22. demo: {
  23. type: Object,
  24. required: true,
  25. },
  26. isRepl: {
  27. type: Boolean,
  28. required: false,
  29. default: () => false,
  30. },
  31. })
  32. const isDev = computed(() => {
  33. return import.meta.env.MODE === 'development'
  34. })
  35. const serverLink = computed(() => {
  36. return unref(isDev) ? '/demoServer' : "https://test.4dkankan.com'"
  37. })
  38. const loadSingleData = computed(() => {
  39. const store = {
  40. 'App.vue': decodeURIComponent(props.raw).replace('#DEMOSEVER#', unref(serverLink)),
  41. }
  42. return window.btoa(JSON.stringify(store))
  43. })
  44. const store = new ReplStore({
  45. // initialize repl with previously serialized state
  46. serializedState: unref(loadSingleData),
  47. // starts on the output pane (mobile only) if the URL has a showOutput query
  48. showOutput: true,
  49. // starts on a different tab on the output pane if the URL has a outputMode query
  50. // and default to the "preview" tab
  51. outputMode: 'preview',
  52. // specify the default URL to import Vue runtime from in the sandbox
  53. // default is the CDN link from unpkg.com with version matching Vue's version
  54. // from peerDependency
  55. defaultVueRuntimeURL: 'https://cdn.jsdelivr.net/npm/@vue/runtime-dom@latest/dist/runtime-dom.esm-browser.js',
  56. })
  57. store.init()
  58. store.setImportMap({
  59. imports: {
  60. vue: 'https://cdn.jsdelivr.net/npm/@vue/runtime-dom@latest/dist/runtime-dom.esm-browser.js',
  61. '@vue/shared': 'https://cdn.jsdelivr.net/npm/@vue/shared@latest/dist/shared.esm-bundler.js',
  62. 'kankan-components': 'https://4dkk.4dage.com/npm_test/kankan-components/dist/index.full.min.mjs',
  63. },
  64. })
  65. const PlaygroundMain = new File('PlaygroundMain.vue', mainCode)
  66. const deptFile = new File('dept.js', deptCode)
  67. store.addFile(PlaygroundMain)
  68. store.addFile(deptFile)
  69. store.state.mainFile = 'PlaygroundMain.vue'
  70. watchEffect(async () => {
  71. if (!unref(props.isRepl)) {
  72. await loadKanKanThemeChalkStyle()
  73. }
  74. })
  75. </script>
  76. <template>
  77. <div class="example-showcase" antialiased>
  78. <ClientOnly>
  79. <template v-if="demo">
  80. <component :is="demo" v-if="!isRepl" v-bind="$attrs" />
  81. <Repl v-else :store="store" :sfc-options="sfcOptions" :clear-console="false" :show-compile-output="false" auto-resize />
  82. </template>
  83. </ClientOnly>
  84. </div>
  85. </template>
  86. <style lang="scss" scoped>
  87. .example-showcase {
  88. padding: 1.5rem;
  89. margin: 0.5px;
  90. background-color: var(--bg-color);
  91. }
  92. </style>
  93. <style lang="scss">
  94. .vue-repl {
  95. height: 650px;
  96. .left {
  97. display: none;
  98. }
  99. .right {
  100. width: 100% !important;
  101. }
  102. // .tab-buttons {
  103. // display: none;
  104. // }
  105. }
  106. </style>