obsidian-visualiser/components/Markdown.vue

89 lines
2.1 KiB
Vue

<template>
<slot
:data="data?.data"
:body="data?.body"
:toc="data?.toc"
:excerpt="data?.excerpt"
:error="error"
>
<MDCRenderer
v-if="body"
:tag="tag"
:class="props.class"
:body="body"
:data="data?.data"
:unwrap="props.unwrap"
:components="{
a: ProseA,
h1: ProseH1,
h2: ProseH2,
h3: ProseH3,
h4: ProseH4,
h5: ProseH5,
h6: ProseH6,
blockquote: ProseBlockquote,
}"
/>
</slot>
</template>
<script setup lang="ts">
import ProseA from "~/components/content/prose/ProseA.vue";
import ProseH1 from "~/components/content/prose/ProseH1.vue";
import ProseH2 from "~/components/content/prose/ProseH2.vue";
import ProseH3 from "~/components/content/prose/ProseH3.vue";
import ProseH4 from "~/components/content/prose/ProseH4.vue";
import ProseH5 from "~/components/content/prose/ProseH5.vue";
import ProseH6 from "~/components/content/prose/ProseH6.vue";
import ProseBlockquote from "~/components/content/prose/ProseBlockquote.vue";
import { hash } from 'ohash'
import { useAsyncData } from 'nuxt/app'
import { watch, computed } from 'vue'
const props = defineProps({
tag: {
type: [String, Boolean],
default: 'div'
},
content: {
type: [String, Object],
required: true
},
excerpt: {
type: Boolean,
default: false
},
class: {
type: [String, Array, Object],
default: ''
},
unwrap: {
type: [Boolean, String],
default: false
}
})
const model = defineModel<number>({
default: 0,
});
const parser = useMarkdown();
const key = computed(() => hash(props.content))
const { data, refresh, error } = await useAsyncData(key.value, async () => {
const timer = performance.now();
if (typeof props.content !== 'string') {
model.value = performance.now() - timer;
return props.content
}
const result = await parser(props.content);
model.value = performance.now() - timer;
return result;
})
const body = computed(() => props.excerpt ? data.value?.excerpt : data.value?.body)
watch(() => props.content, () => {
refresh()
})
</script>