vp-example.vue 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  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.js?raw'
  6. import { loadKanKanThemeChalkStyle } from './dept-home'
  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. console.log('isDev', unref(isDev))
  36. const serverLink = computed(() => {
  37. return unref(isDev) ? '/demoServer' : 'https://test.4dkankan.com/'
  38. })
  39. // const loadSingleData = computed(() => {
  40. // const store = {
  41. // 'App.vue': decodeURIComponent(props.raw).replace('#DEMOSEVER#', unref(serverLink)),
  42. // }
  43. // return window.btoa(JSON.stringify(store))
  44. // })
  45. const store = new ReplStore({
  46. // initialize repl with previously serialized state
  47. // serializedState: unref(loadSingleData),
  48. // starts on the output pane (mobile only) if the URL has a showOutput query
  49. showOutput: true,
  50. // starts on a different tab on the output pane if the URL has a outputMode query
  51. // and default to the "preview" tab
  52. outputMode: 'preview',
  53. // specify the default URL to import Vue runtime from in the sandbox
  54. // default is the CDN link from unpkg.com with version matching Vue's version
  55. // from peerDependency
  56. defaultVueRuntimeURL: 'https://cdn.jsdelivr.net/npm/@vue/runtime-dom@latest/dist/runtime-dom.esm-browser.js',
  57. })
  58. store.init()
  59. watchEffect(async () => {
  60. if (!unref(props.isRepl)) {
  61. await loadKanKanThemeChalkStyle()
  62. } else {
  63. if (unref(props.raw)) {
  64. store.setImportMap({
  65. imports: {
  66. vue: 'https://cdn.jsdelivr.net/npm/@vue/runtime-dom@latest/dist/runtime-dom.esm-browser.js',
  67. '@vue/shared': 'https://cdn.jsdelivr.net/npm/@vue/shared@latest/dist/shared.esm-bundler.js',
  68. 'kankan-components': 'https://4dkk.4dage.com/npm_test/kankan-components/dist/index.full.min.mjs',
  69. },
  70. })
  71. const mainFile = new File('PlaygroundMain.vue', mainCode)
  72. const deptFile = new File('dept.js', deptCode)
  73. const appFile = new File('App.vue', decodeURIComponent(props.raw).replace('#DEMOSEVER#', unref(serverLink)))
  74. store.addFile(mainFile)
  75. store.addFile(appFile)
  76. store.addFile(deptFile)
  77. store.state.mainFile = 'PlaygroundMain.vue'
  78. store.state.activeFile = appFile
  79. console.log('appFile', appFile)
  80. }
  81. }
  82. })
  83. console.log('store', store)
  84. </script>
  85. <template>
  86. <div class="example-showcase" antialiased>
  87. <ClientOnly>
  88. <template v-if="demo">
  89. <component :is="demo" v-if="!isRepl" v-bind="$attrs" />
  90. <Repl v-else ref="repl" :store="store" v-bind="$attrs" :sfc-options="sfcOptions" :clear-console="false" :show-compile-output="true" auto-resize />
  91. </template>
  92. </ClientOnly>
  93. </div>
  94. </template>
  95. <style lang="scss" scoped>
  96. .example-showcase {
  97. padding: 1.5rem;
  98. margin: 0.5px;
  99. background-color: var(--bg-color);
  100. }
  101. </style>
  102. <style lang="scss">
  103. .vue-repl {
  104. height: 650px;
  105. .left {
  106. display: none;
  107. }
  108. .right {
  109. width: 100% !important;
  110. }
  111. // .tab-buttons {
  112. // display: none;
  113. // }
  114. }
  115. </style>