first commit

This commit is contained in:
2025-02-23 21:26:12 +08:00
commit 3b26fe4adc
23 changed files with 2527 additions and 0 deletions

56
src/components/Editor.vue Normal file
View File

@@ -0,0 +1,56 @@
<script lang="ts" setup>
import { EditorView } from "@codemirror/view"
import { Codemirror } from "vue-codemirror"
import { oneDark } from "../themes/oneDark.ts"
import { smoothy } from "../themes/smoothy.ts"
import { useDark } from "@vueuse/core"
import { computed } from "vue"
import { css } from "@codemirror/lang-css"
import { javascript } from "@codemirror/lang-javascript"
import { html } from "@codemirror/lang-html"
const styleTheme = EditorView.baseTheme({
"& .cm-scroller": {
"font-family": "Monaco",
},
"&.cm-editor.cm-focused": {
outline: "none",
},
"&.cm-editor .cm-tooltip.cm-tooltip-autocomplete ul": {
"font-family": "Monaco",
},
})
interface Props {
language?: "html" | "css" | "js"
fontSize?: number
}
const props = withDefaults(defineProps<Props>(), {
language: "html",
fontSize: 20,
})
const code = defineModel<string>("value")
const isDark = useDark()
const lang = computed(() => {
if (props.language === "html") {
return html()
} else if (props.language === "css") {
return css()
} else {
return javascript()
}
})
</script>
<template>
<Codemirror
v-model="code"
indentWithTab
:extensions="[styleTheme, lang, isDark ? oneDark : smoothy]"
:tabSize="4"
:style="{ height: 'calc(100vh - 52px)', fontSize: props.fontSize + 'px' }"
/>
</template>

View File

@@ -0,0 +1,41 @@
<template>
<iframe class="iframe" ref="iframe"></iframe>
</template>
<script lang="ts" setup>
import { html, css } from "../store.ts"
import { onMounted, useTemplateRef, watch } from "vue"
const iframe = useTemplateRef<HTMLIFrameElement>("iframe")
function preview() {
if (!iframe.value) return
const doc = iframe.value.contentDocument
doc!.open()
doc!.write(`<!DOCTYPE html>
<html lang="zh-Hans-CN">
<head>
<meta charset="UTF-8" />
<title>预览</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<style>${css.value}</style>
</head>
<body>
${html.value}
</body>
</html>`)
doc!.close()
}
watch([html, css], preview)
onMounted(preview)
</script>
<style scoped>
.iframe {
width: 100%;
height: 100%;
border: none;
outline: none;
}
</style>