chore(sfc-playground): update code style and syntax

This commit is contained in:
Evan You
2021-08-17 15:42:18 -04:00
parent ceace3a8cc
commit e22d7cdb08
8 changed files with 184 additions and 157 deletions

View File

@@ -1,6 +1,24 @@
<script setup lang="ts">
import Preview from './Preview.vue'
import CodeMirror from '../codemirror/CodeMirror.vue'
import { store } from '../store'
import { ref } from 'vue'
const modes = ['preview', 'js', 'css', 'ssr'] as const
type Modes = typeof modes[number]
const mode = ref<Modes>('preview')
</script>
<template>
<div class="tab-buttons">
<button v-for="m of modes" :class="{ active: mode === m }" @click="mode = m">{{ m }}</button>
<button
v-for="m of modes"
:class="{ active: mode === m }"
@click="mode = m"
>
{{ m }}
</button>
</div>
<div class="output-container">
@@ -14,18 +32,6 @@
</div>
</template>
<script setup lang="ts">
import Preview from './Preview.vue'
import CodeMirror from '../codemirror/CodeMirror.vue'
import { store } from '../store'
import { ref } from 'vue'
const modes = ['preview', 'js', 'css', 'ssr'] as const
type Modes = typeof modes[number]
const mode = ref<Modes>('preview')
</script>
<style scoped>
.output-container {
height: calc(100% - 35px);

View File

@@ -1,14 +1,13 @@
<template>
<div class="preview-container" ref="container">
</div>
<Message :err="runtimeError" />
<Message v-if="!runtimeError" :warn="runtimeWarning" />
</template>
<script setup lang="ts">
import Message from '../Message.vue'
import { ref, onMounted, onUnmounted, watchEffect, watch } from 'vue'
import type { WatchStopHandle } from 'vue'
import {
ref,
onMounted,
onUnmounted,
watchEffect,
watch,
WatchStopHandle
} from 'vue'
import srcdoc from './srcdoc.html?raw'
import { PreviewProxy } from './PreviewProxy'
import { MAIN_FILE, vueRuntimeUrl } from '../sfcCompiler'
@@ -27,34 +26,35 @@ let stopUpdateWatcher: WatchStopHandle
onMounted(createSandbox)
// reset sandbox when import map changes
watch(() => store.importMap, (importMap, prev) => {
if (!importMap) {
if (prev) {
// import-map.json deleted
createSandbox()
}
return
}
try {
const map = JSON.parse(importMap)
if (!map.imports) {
store.errors = [
`import-map.json is missing "imports" field.`
]
watch(
() => store.importMap,
(importMap, prev) => {
if (!importMap) {
if (prev) {
// import-map.json deleted
createSandbox()
}
return
}
if (map.imports.vue) {
store.errors = [
'Select Vue versions using the top-right dropdown.\n' +
'Specifying it in the import map has no effect.'
]
try {
const map = JSON.parse(importMap)
if (!map.imports) {
store.errors = [`import-map.json is missing "imports" field.`]
return
}
if (map.imports.vue) {
store.errors = [
'Select Vue versions using the top-right dropdown.\n' +
'Specifying it in the import map has no effect.'
]
}
createSandbox()
} catch (e) {
store.errors = [e as Error]
return
}
createSandbox()
} catch (e) {
store.errors = [e]
return
}
})
)
// reset sandbox when version changes
watch(vueRuntimeUrl, createSandbox)
@@ -73,21 +73,24 @@ function createSandbox() {
}
sandbox = document.createElement('iframe')
sandbox.setAttribute('sandbox', [
'allow-forms',
'allow-modals',
'allow-pointer-lock',
'allow-popups',
'allow-same-origin',
'allow-scripts',
'allow-top-navigation-by-user-activation'
].join(' '))
sandbox.setAttribute(
'sandbox',
[
'allow-forms',
'allow-modals',
'allow-pointer-lock',
'allow-popups',
'allow-same-origin',
'allow-scripts',
'allow-top-navigation-by-user-activation'
].join(' ')
)
let importMap: Record<string, any>
try {
importMap = JSON.parse(store.importMap || `{}`)
} catch (e) {
store.errors = [`Syntax error in import-map.json: ${e.message}`]
store.errors = [`Syntax error in import-map.json: ${(e as Error).message}`]
return
}
@@ -95,7 +98,10 @@ function createSandbox() {
importMap.imports = {}
}
importMap.imports.vue = vueRuntimeUrl.value
const sandboxSrc = srcdoc.replace(/<!--IMPORT_MAP-->/, JSON.stringify(importMap))
const sandboxSrc = srcdoc.replace(
/<!--IMPORT_MAP-->/,
JSON.stringify(importMap)
)
sandbox.srcdoc = sandboxSrc
container.value.appendChild(sandbox)
@@ -104,13 +110,15 @@ function createSandbox() {
// pending_imports = progress;
},
on_error: (event: any) => {
const msg = event.value instanceof Error ? event.value.message : event.value
const msg =
event.value instanceof Error ? event.value.message : event.value
if (
msg.includes('Failed to resolve module specifier') ||
msg.includes('Error resolving module specifier')
) {
runtimeError.value = msg.replace(/\. Relative references must.*$/, '') +
`.\nTip: add an "import-map.json" file to specify import paths for dependencies.`
runtimeError.value =
msg.replace(/\. Relative references must.*$/, '') +
`.\nTip: add an "import-map.json" file to specify import paths for dependencies.`
} else {
runtimeError.value = event.value
}
@@ -173,24 +181,30 @@ async function updatePreview() {
`window.__modules__ = {};window.__css__ = ''`,
...modules,
`
import { createApp as _createApp } from "vue"
if (window.__app__) {
window.__app__.unmount()
document.getElementById('app').innerHTML = ''
}
document.getElementById('__sfc-styles').innerHTML = window.__css__
const app = window.__app__ = _createApp(__modules__["${MAIN_FILE}"].default)
app.config.errorHandler = e => console.error(e)
app.mount('#app')`.trim()
import { createApp as _createApp } from "vue"
if (window.__app__) {
window.__app__.unmount()
document.getElementById('app').innerHTML = ''
}
document.getElementById('__sfc-styles').innerHTML = window.__css__
const app = window.__app__ = _createApp(__modules__["${MAIN_FILE}"].default)
app.config.errorHandler = e => console.error(e)
app.mount('#app')`.trim()
])
} catch (e) {
runtimeError.value = e.message
runtimeError.value = (e as Error).message
}
}
</script>
<template>
<div class="preview-container" ref="container"></div>
<Message :err="runtimeError" />
<Message v-if="!runtimeError" :warn="runtimeWarning" />
</template>
<style>
.preview-container,
iframe {