123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- <script setup lang="ts">
- import { computed, unref, watchEffect } from 'vue'
- import { File, Repl, ReplStore } from '@vue/repl'
- import mainCode from './main.vue?raw'
- import deptCode from './dept.js?raw'
- import { loadKanKanThemeChalkStyle } from './dept-home'
- import type { SFCOptions } from '@vue/repl'
- const sfcOptions: SFCOptions = {
- script: {
- reactivityTransform: true,
- },
- }
- const props = defineProps({
- file: {
- type: String,
- required: true,
- },
- raw: {
- type: String,
- required: true,
- },
- demo: {
- type: Object,
- required: true,
- },
- isRepl: {
- type: Boolean,
- required: false,
- default: () => false,
- },
- })
- const isDev = computed(() => {
- return import.meta.env.MODE === 'development'
- })
- const serverLink = computed(() => {
- return unref(isDev) ? '/demoServer' : 'https://test.4dkankan.com/'
- })
- const store = new ReplStore({
- // initialize repl with previously serialized state
- // serializedState: unref(loadSingleData),
- // starts on the output pane (mobile only) if the URL has a showOutput query
- showOutput: true,
- // starts on a different tab on the output pane if the URL has a outputMode query
- // and default to the "preview" tab
- outputMode: 'preview',
- // specify the default URL to import Vue runtime from in the sandbox
- // default is the CDN link from unpkg.com with version matching Vue's version
- // from peerDependency
- defaultVueRuntimeURL:
- 'https://cdn.jsdelivr.net/npm/@vue/runtime-dom@latest/dist/runtime-dom.esm-browser.js',
- })
- watchEffect(async () => {
- if (!unref(props.isRepl)) {
- await loadKanKanThemeChalkStyle()
- } else {
- if (unref(props.raw)) {
- store.setImportMap({
- imports: {
- vue: 'https://cdn.jsdelivr.net/npm/@vue/runtime-dom@latest/dist/runtime-dom.esm-browser.js',
- '@vue/shared':
- 'https://cdn.jsdelivr.net/npm/@vue/shared@latest/dist/shared.esm-bundler.js',
- 'kankan-components':
- 'https://4dkk.4dage.com/npm_test/kankan-components/dist/index.full.min.mjs',
- },
- })
- const mainFile = new File('PlaygroundMain.vue', mainCode)
- const deptFile = new File('dept.js', deptCode)
- const appFile = new File(
- 'App.vue',
- decodeURIComponent(props.raw).replace('#DEMOSEVER#', unref(serverLink))
- )
- store.addFile(mainFile)
- store.addFile(appFile)
- store.addFile(deptFile)
- store.state.mainFile = 'PlaygroundMain.vue'
- store.state.activeFile = appFile
- store.init()
- }
- }
- })
- </script>
- <template>
- <div class="example-showcase" antialiased>
- <ClientOnly>
- <template v-if="demo">
- <component :is="demo" v-if="!isRepl" v-bind="$attrs" />
- <Repl
- v-else
- ref="repl"
- :store="store"
- v-bind="$attrs"
- :sfc-options="sfcOptions"
- :clear-console="false"
- :show-compile-output="true"
- auto-resize
- />
- </template>
- </ClientOnly>
- </div>
- </template>
- <style lang="scss" scoped>
- .example-showcase {
- padding: 1.5rem;
- margin: 0.5px;
- background-color: var(--bg-color);
- }
- </style>
- <style lang="scss">
- .vue-repl {
- height: 650px;
- .left {
- display: none;
- }
- .right {
- width: 100% !important;
- }
- // .tab-buttons {
- // display: none;
- // }
- }
- </style>
|