You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
78 lines
2.1 KiB
78 lines
2.1 KiB
<script setup lang="ts">
|
|
import { MdEditor, config as mdEditorGlobalConfig } from 'md-editor-v3'
|
|
import 'md-editor-v3/lib/style.css'
|
|
import { attachMarkdownItStripFrontMatter } from '../utils/markdown-front-matter'
|
|
|
|
const props = defineProps<{
|
|
modelValue: string
|
|
}>()
|
|
|
|
const emit = defineEmits<{
|
|
'update:modelValue': [string]
|
|
}>()
|
|
|
|
const { fetchData } = useClientApi()
|
|
const toast = useToast()
|
|
const editorId = `post-body-md-${useId()}`
|
|
|
|
/**
|
|
* md-editor-v3 不会把 `markdown-it-config` 传给内部预览组件;预览用的 MarkdownIt 只读全局 `config()`。
|
|
* @see node_modules/md-editor-v3/lib/es/MdEditor.mjs — ContentPreview 未转发 markdownItConfig
|
|
*/
|
|
let mdEditorStripFmInstalled = false
|
|
function ensureMdEditorStripFrontMatter() {
|
|
if (mdEditorStripFmInstalled) {
|
|
return
|
|
}
|
|
mdEditorStripFmInstalled = true
|
|
mdEditorGlobalConfig({
|
|
markdownItConfig(md) {
|
|
attachMarkdownItStripFrontMatter(md, 'person_panel_strip_fm')
|
|
},
|
|
})
|
|
}
|
|
ensureMdEditorStripFrontMatter()
|
|
|
|
const local = computed({
|
|
get: () => props.modelValue,
|
|
set: (v: string) => emit('update:modelValue', v),
|
|
})
|
|
|
|
async function onUploadImg(files: File[], callback: (urls: string[]) => void) {
|
|
const form = new FormData()
|
|
for (const f of files) {
|
|
form.append('file', f)
|
|
}
|
|
try {
|
|
const { files: uploaded } = await fetchData<{ files: { url: string }[] }>('/api/file/upload', {
|
|
method: 'POST',
|
|
body: form,
|
|
})
|
|
toast.add({ title: '图片已上传', color: 'success' })
|
|
callback(uploaded.map((x) => x.url))
|
|
} catch {
|
|
callback([])
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<ClientOnly>
|
|
<MdEditor
|
|
:id="editorId"
|
|
v-model="local"
|
|
language="zh-CN"
|
|
:preview="true"
|
|
preview-theme="github"
|
|
theme="light"
|
|
:on-upload-img="onUploadImg"
|
|
:style="{ height: 'min(72vh, 720px)' }"
|
|
class="w-full rounded-lg overflow-hidden ring ring-default"
|
|
/>
|
|
<template #fallback>
|
|
<div class="text-muted text-sm py-12 text-center border border-default rounded-lg">
|
|
编辑器加载中…
|
|
</div>
|
|
</template>
|
|
</ClientOnly>
|
|
</template>
|
|
|