1. 问题说明
一般来说,要渲染 HTML 内容我们用 v-html
指令传递内容就可以了:
<div v-html="<p>段落</p>"></div>
如果这里不是一个 div
标签,而是一个自定义组件:
<CustomElement v-html="<p>段落</p>"></CustomElement>
在服务端渲染(SSR)时,HTML 内容是不会被渲染出来的。
然而有时候还真有这样的应用场景,比如在展示文章内容时,我们经常会自定义其展示样式,用 JavaScript 处理代码块的一键复制等。将内容放到自定义组件中统一处理显然是个不错的选择。怎么实现呢?
2. 解决方案
既然 v-html
作用在自定义组件上有问题,我们通过 props
传递即可:
Typography.vue
<template>
<div v-if="htmlContent" v-bind="$attrs" v-html="html"></div>
<div v-else v-bind="$attrs">
<slot></slot>
</div>
</template>
<script setup>
defineOptions({
inheritAttrs: false
});
const props = defineProps({
html: String
});
</script>
有两种使用方式:
在 Vue 组件中,通过插槽传递内容:
<Typography>
<p>段落</p>
<Typography>
对于博客、CMS 等存储在数据库中的 HTML 内容,通过 props
传递内容:
<Typography html="<p>段落</p>" />