在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 内容,还能有效地监听内容的变化并重新渲染。

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

相关文章

  • vite构建项目并支持微前端

    vite构建项目并支持微前端

    本文主要介绍了vite构建项目并支持微前端,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-01-01
  • vue 中Virtual Dom被创建的方法

    vue 中Virtual Dom被创建的方法

    本文将通过解读render函数的源码,来分析vue中的vNode是如何创建的,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-04-04
  • Vue3使用Proxy构建高效响应式数据的示例代码

    Vue3使用Proxy构建高效响应式数据的示例代码

    在 Vue 3 中,Proxy 主要用于 拦截对象的基本操作,包括 属性读取(get)、修改(set)、删除(deleteProperty) 等,本文给大家介绍了Vue3使用Proxy构建高效响应式数据的操作教程,需要的朋友可以参考下
    2025-03-03
  • 如何用webpack4带你实现一个vue的打包的项目

    如何用webpack4带你实现一个vue的打包的项目

    这篇文章主要介绍了如何用webpack4带你实现一个vue的打包的项目,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-06-06
  • 极速上手 VUE 3 teleport传送门组件及使用语法

    极速上手 VUE 3 teleport传送门组件及使用语法

    teleport 传送门组件,提供一种简洁的方式,可以指定它里面的内容的父元素,也就是说teleport 中的内容允许我们控制在任意的DOM中,使用简单,对VUE 3 teleport传送门相关知识感兴趣的朋友一起看看吧
    2021-10-10
  • Vue2模版编译流程详解

    Vue2模版编译流程详解

    vue中有一张响应式系统的流程图,vue会将模板语法编译成render函数,通过render函数渲染生成Virtual dom,但是官方并没有对模板编译有详细的介绍,这篇文章带大家一起学习下vue的模板编译
    2023-07-07
  • Proxy中代理数据拦截的方法详解

    Proxy中代理数据拦截的方法详解

    这篇文章主要为大家详细介绍了Proxy中代理数据拦截的方法,文中的示例代码讲解详细,对我们学习或工作具有一定的借鉴价值,需要的可以参考一下
    2022-12-12
  • Vue注册组件命名时不能用大写的原因浅析

    Vue注册组件命名时不能用大写的原因浅析

    这段时间一直在弄vue,当然也遇到很多问题,这里就来跟大家分享一些注册自定义模板组件的心得 ,需要的朋友可以参考下
    2019-04-04
  • Vue中

    Vue中"This dependency was not found"问题的解决方法

    这篇文章主要介绍了Vue中"This dependency was not found"的问题的解决方法,需要的朋友可以参考下
    2018-06-06
  • Vue动态路由缓存不相互影响的解决办法

    Vue动态路由缓存不相互影响的解决办法

    这篇文章主要介绍了Vue动态路由缓存不相互影响的解决办法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-02-02

最新评论