在Vue3中实现一个自定义的v-html组件方式

 更新时间:2025年11月03日 09:36:22   作者:斯~内克  
文章介绍了Vue.js中的v-html指令及其潜在的安全风险,然后通过DOMParser实现了一个自定义的v-html组件,以提高安全性并避免XSS攻击

引言

在 Vue.js 中,v-html 是一个非常有用的指令,用于将 HTML 字符串渲染到元素中。然而,由于它直接插入 HTML 内容,存在潜在的安全风险(如 XSS 攻击)。

因此,了解其工作原理并实现一个安全的替代方案是非常重要的。

v-html原理

v-html 的主要功能包括:

  • 将字符串内容作为 HTML 插入到指定的 DOM 元素中。
  • 不会进行任何的 HTML 转义,因此可以插入完整的 HTML 结构。
  • 由于其直接插入 HTML 的特性,使用时需要非常小心,以防止 XSS 攻击。

实现一个自定义的v-html组件

为了实现一个安全的 HTML 渲染组件,我们可以使用 DOMParser 来解析和处理 HTML 内容。

以下是一个详细的实现步骤。

步骤

  1. 定义一个 prop 来接收 HTML 字符串。
  2. 使用 DOMParser 解析 HTML 字符串。
  3. 将解析后的 DOM 内容插入到组件的模板中。
  4. 监听 prop 的变化,以便在内容变化时重新渲染。

实现代码

假设我们有一个 YHtml.vue 组件,我们将在这个组件中实现自定义的 v-html 功能。

<template>
  <div ref="htmlContainer"></div>
</template>

<script setup lang="ts">
import { onMounted, ref, watch } from 'vue'

// 定义一个 prop 来接收 HTML 字符串
const props = defineProps<{
  htmlContent: string
}>()

// 获取对 DOM 元素的引用
const htmlContainer = ref<HTMLElement | null>(null)

// 使用 DOMParser 解析 HTML 字符串并插入到容器中
const renderHtml = () => {
  if (htmlContainer.value) {
    const parser = new DOMParser()
    const doc = parser.parseFromString(props.htmlContent, 'text/html')
    const body = doc.body

    // 清空容器
    htmlContainer.value.innerHTML = ''

    // 将解析后的 HTML 内容插入到容器中
    Array.from(body.childNodes).forEach(node => {
      htmlContainer.value?.appendChild(node)
    })
  }
}

// 在组件挂载时渲染 HTML
onMounted(() => {
  renderHtml()
})

// 监听 htmlContent 的变化,重新渲染 HTML
watch(() => props.htmlContent, renderHtml)
</script>

<style scoped>
/* 添加样式 */
</style>

使用示例

假设你在父组件中使用 YHtml 组件,可以这样写:

<template>
  <div>
    <YHtml :htmlContent="htmlString" />
  </div>
</template>

<script setup lang="ts">
import YHtml from './components/YHtml.vue'
import { ref } from 'vue'

const htmlString = ref('<p>这是一个 <strong>安全</strong> 的 HTML 内容。</p>')
</script>

注意事项

  • 安全性:虽然我们使用了 DOMParser 来解析 HTML,但在实际应用中,还需要对输入的 HTML 进行严格的过滤和验证,以防止 XSS 攻击。
  • 性能:频繁地操作 DOM 可能会影响性能,特别是在处理大量或复杂的 HTML 内容时。

总结

通过以上步骤,你可以在 Vue 3 中实现一个自定义的 v-html 组件。这个组件不仅能够安全地渲染 HTML 内容,还能有效地监听内容的变化并重新渲染。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Vue使用vue-area-linkage实现地址三级联动效果的示例

    Vue使用vue-area-linkage实现地址三级联动效果的示例

    很多时候我们需要使用地址三级联动,即省市区三级联动,这篇文章主要介绍了Vue使用vue-area-linkage实现地址三级联动效果的示例,感兴趣的小伙伴们可以参考一下
    2018-06-06
  • vue项目页面的打印和下载PDF加loading效果的实现(加水印)

    vue项目页面的打印和下载PDF加loading效果的实现(加水印)

    这篇文章主要介绍了vue项目页面的打印和下载PDF加loading效果的实现(加水印),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12
  • vue-cli3中vue.config.js配置教程详解

    vue-cli3中vue.config.js配置教程详解

    这篇文章主要介绍了vue-cli3中vue.config.js配置教程,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-05-05
  • 在nuxt使用vueX代替storage的实现方案

    在nuxt使用vueX代替storage的实现方案

    这篇文章主要介绍了在nuxt使用vueX代替storage的实现方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-10-10
  • element-plus的el-table自定义表头筛选查询功能实现

    element-plus的el-table自定义表头筛选查询功能实现

    这篇文章主要介绍了element-plus的el-table自定义表头筛选查询功能实现,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2024-07-07
  • VUE mixin 使用示例详解

    VUE mixin 使用示例详解

    混入mixin提供了一种非常灵活的方式,来分发Vue组件中的可复用功能,一个混入对象可以包含任意组件选项,接下来通过本文给大家介绍VUE mixin 使用,需要的朋友可以参考下
    2022-08-08
  • Vue使用echarts散点图在区域内标点

    Vue使用echarts散点图在区域内标点

    这篇文章主要为大家详细介绍了Vue使用echarts散点图在区域内标点,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • Vue仿今日头条实例详解

    Vue仿今日头条实例详解

    这篇文章主要介绍了Vue仿今日头条实例详解,并把相关代码做了说明,对此有兴趣的朋友参考下吧。
    2018-02-02
  • Vue-CLI项目中路由传参的方式详解

    Vue-CLI项目中路由传参的方式详解

    这篇文章主要介绍了Vue-CLI项目中路由传参的方式详解,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-09-09
  • 基于vue3 vue-cli4 线上部署及优化的问题

    基于vue3 vue-cli4 线上部署及优化的问题

    这篇文章主要介绍了基于vue3 vue-cli4 线上部署及优化的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-06-06

最新评论