|
| 1 | +<script setup lang="ts"> |
| 2 | +import type { OutputModes } from '@vue/repl' |
| 3 | +import type { ShallowRef } from 'vue' |
| 4 | +import { mergeImportMap, Repl, useStore, useVueImportMap } from '@vue/repl' |
| 5 | +import CodeMirror from '@vue/repl/codemirror-editor' |
| 6 | +
|
| 7 | +const showOutput = useRouteQuery<string, boolean>('showOutput', 'false', { transform: { |
| 8 | + get(value) { |
| 9 | + if (value === 'false' || value === '0') |
| 10 | + return false |
| 11 | + else return Boolean(value) |
| 12 | + }, |
| 13 | + set(value) { |
| 14 | + return String(value) |
| 15 | + }, |
| 16 | +} }) |
| 17 | +
|
| 18 | +const outputMode = useRouteQuery<OutputModes, OutputModes>('outputMode', 'preview') |
| 19 | +
|
| 20 | +const hash = useRouteHash(undefined, { mode: 'replace' }) |
| 21 | +
|
| 22 | +const { |
| 23 | + importMap: builtinImportMap, |
| 24 | + vueVersion, |
| 25 | + productionMode, |
| 26 | +} = useVueImportMap() |
| 27 | +
|
| 28 | +const injectedVueVersion = inject<ShallowRef<string>>('vueVersion', shallowRef<string>('latest')) |
| 29 | +
|
| 30 | +const vueuseVersion = useRouteQuery('vueuse', 'latest') |
| 31 | +
|
| 32 | +const vueUsePackages = [ |
| 33 | + '@vueuse/metadata', |
| 34 | + '@vueuse/shared', |
| 35 | + '@vueuse/core', |
| 36 | + '@vueuse/integrations', |
| 37 | + '@vueuse/math', |
| 38 | + '@vueuse/rxjs', |
| 39 | +] |
| 40 | +
|
| 41 | +function generateVueUseImportCDNs() { |
| 42 | + return vueUsePackages.map((p) => { |
| 43 | + return [p, `https://cdn.jsdelivr.net/npm/${p}@${vueuseVersion.value}/index.mjs`] |
| 44 | + }) |
| 45 | +} |
| 46 | +
|
| 47 | +const importMap = computed(() => { |
| 48 | + return mergeImportMap(builtinImportMap.value, { |
| 49 | + imports: Object.fromEntries([...generateVueUseImportCDNs(), ['vue-demi', 'https://cdn.jsdelivr.net/npm/[email protected]/lib/index.mjs']]), |
| 50 | + }) |
| 51 | +}) |
| 52 | +
|
| 53 | +const { template } = useTemplate() |
| 54 | +
|
| 55 | +const store = useStore( |
| 56 | + { |
| 57 | + // pre-set import map |
| 58 | + builtinImportMap: importMap, |
| 59 | + vueVersion, |
| 60 | + // starts on the output pane (mobile only) if the URL has a showOutput query |
| 61 | + showOutput, |
| 62 | + // starts on a different tab on the output pane if the URL has a outputMode query |
| 63 | + // and default to the "preview" tab |
| 64 | + outputMode, |
| 65 | + template, |
| 66 | + }, |
| 67 | + // initialize repl with previously serialized state |
| 68 | + hash.value ?? undefined, |
| 69 | +) |
| 70 | +
|
| 71 | +injectedVueVersion.value = vueVersion.value ?? 'latest' |
| 72 | +
|
| 73 | +// persist state to URL hash |
| 74 | +watchEffect(() => hash.value = store.serialize()) |
| 75 | +
|
| 76 | +// production mode is enabled |
| 77 | +productionMode.value = true |
| 78 | +
|
| 79 | +watch(() => injectedVueVersion.value, (newVersion) => { |
| 80 | + vueVersion.value = newVersion |
| 81 | +}) |
| 82 | +</script> |
| 83 | + |
| 84 | +<template> |
| 85 | + <Repl :store="store" :editor="CodeMirror" :show-compile-output="true" /> |
| 86 | +</template> |
0 commit comments