feat: 优化md渲染组件性能表现
This commit is contained in:
1 parent
c1be93739d
commit
d20dc84d9d
4 files changed
+44
-31
No files matched your search
@@ -4,17 +4,19 @@
|
||||
<div class="md-render-wrapper markdown-body">
|
||||
<VNodeMD v-if="VNodeMD && props.data"></VNodeMD>
|
||||
<div v-else>
|
||||
<el-skeleton :rows="12" />
|
||||
<el-skeleton v-if="!props.disableSkeleton" :rows="12" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import codemirrorMiddleware from '~/hooks/h2v/codemirrorMiddleware';
|
||||
import useMarkdownit from '~/hooks/useMarkdownit';
|
||||
import Html2VNode from '~/utils/html2VNode';
|
||||
|
||||
const props = defineProps<{
|
||||
data: string
|
||||
disableSkeleton?: boolean
|
||||
}>()
|
||||
|
||||
const VNodeMD = shallowRef<any>()
|
||||
@@ -26,31 +28,7 @@ watch(() => props.data, async () => {
|
||||
const markdownIt = await useMarkdownit()
|
||||
const renderedData = markdownIt.render(props.data)
|
||||
const h2v = new Html2VNode()
|
||||
h2v.use(
|
||||
{
|
||||
filter(tagName) {
|
||||
return tagName === 'code'
|
||||
},
|
||||
async render({
|
||||
item,
|
||||
tagAttrs,
|
||||
}) {
|
||||
const codeMirror = (await import('./codeMirror.vue')).default
|
||||
const codeType = tagAttrs?.class?.slice(1, -1)?.split('-')?.[1] ?? ''
|
||||
// @ts-ignore
|
||||
const inline = (item.children[0].children.trim() as string).includes('\n') ? false : true
|
||||
return h(
|
||||
codeMirror,
|
||||
{
|
||||
// @ts-ignore
|
||||
data: item.children[0].children.trim(),
|
||||
type: codeType,
|
||||
inline,
|
||||
},
|
||||
)
|
||||
},
|
||||
}
|
||||
)
|
||||
h2v.use(codemirrorMiddleware)
|
||||
const res = await h2v.render(renderedData)
|
||||
VNodeMD.value = {
|
||||
setup: () => {
|
||||
@@ -61,10 +39,6 @@ watch(() => props.data, async () => {
|
||||
immediate: true
|
||||
})
|
||||
|
||||
// watch(() => renderedData.value, () => {
|
||||
// _key.value = Math.random()
|
||||
// })
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
<el-input v-if="isEditing" type="textarea" v-model:model-value="content" placeholder="content"
|
||||
:autosize="{ minRows: 15 }" :disabled="disabled" />
|
||||
<div class=" border-1 border-gray-300 rounded-sm p-2" v-else>
|
||||
<markdown-render :data="content ?? ''" />
|
||||
<markdown-render :data="content ?? ''" :disable-skeleton="true" />
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
const codemirrorMiddleware: middlewareType = {
|
||||
filter(tagName: string) {
|
||||
return tagName === 'code'
|
||||
},
|
||||
async render({
|
||||
item,
|
||||
tagAttrs,
|
||||
}) {
|
||||
const codeMirror = await cachedPromise('component:codeMirror', async () => {
|
||||
const codeMirror = (await import('~/components/codeMirror.vue')).default
|
||||
return codeMirror
|
||||
})
|
||||
const codeType = tagAttrs?.class?.slice(1, -1)?.split('-')?.[1] ?? ''
|
||||
// @ts-ignore
|
||||
const inline = (item.children[0].children.trim() as string).includes('\n') ? false : true
|
||||
return h(
|
||||
codeMirror,
|
||||
{
|
||||
// @ts-ignore
|
||||
data: item.children[0].children.trim(),
|
||||
type: codeType,
|
||||
inline,
|
||||
},
|
||||
)
|
||||
},
|
||||
}
|
||||
|
||||
export default codemirrorMiddleware
|
||||
@@ -0,0 +1,11 @@
|
||||
import useDefaultStore from "~/hooks/pinia/useDefaultStore"
|
||||
|
||||
export default async function cachedPromise<T>(key: string, promise: () =>Promise<T>): Promise<T> {
|
||||
const cache = useDefaultStore().getCache(key)
|
||||
if (cache) {
|
||||
return cache
|
||||
}
|
||||
const res = await promise()
|
||||
useDefaultStore().setCache(key, res)
|
||||
return res
|
||||
}
|
||||
Reference in new issue
Block a user