当前位置: 首页 > 知识库问答 >
问题:

javascript - 相同的HTML代码,用v-html与直接写在模板中染相表现差异巨大,如何规避?

平元明
2024-09-18

可以通过下面的链接查看问题,template里面的html与v-html是一样的代码,但是表现差异巨大
DEMO

共有3个答案

伏砚
2024-09-18

和编写 tempaltev-html 没有关系。
只是因为你的 viewBox 拼写错了,修改成 viewBox 就行了。

<script setup>

const html = `<section><section><section style="margin: 10px auto; display: flex; justify-content: center; padding-bottom: 5px; box-sizing: border-box;"><section style="display: flex; flex-direction: column;"><section class="assistant" style="width: 35px; margin-left: auto; box-sizing: border-box;"><img src="https://oss.tccms.cn/1sqnkqGnuBk" draggable="false" class="assistant" style="width: 100%; display: block; vertical-align: baseline; box-sizing: border-box; max-width: 100% !important;"></section><section style="display: flex; flex-direction: column; margin: 0px 20px; z-index: 3;"><section style="font-size: 16px; color: rgb(255, 255, 255); text-align: center; z-index: 4;"><strong>Haha</strong></section><section style="width: 150px; margin: -43px auto 0px; box-sizing: border-box;"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 219 81" xml:space="default" style="display: block;"><g id="图层_2"><g id="图层_1-2"><polygon points="212 9 207 0 18 9 9 10 0 59 18 81 207 81 219 22 211.91 9 212 9" style="fill: rgb(112, 204, 251); fill-rule: evenodd;"></polygon><path d="M13.71,47.59a5,5,0,1,1-5,5A5,5,0,0,1,13.71,47.59Z" style="fill: rgb(255, 255, 255); fill-rule: evenodd;"></path><path d="M16.71,31.59a5,5,0,1,1-5,5A5,5,0,0,1,16.71,31.59Z" style="fill: rgb(255, 255, 255); fill-rule: evenodd;"></path><path d="M19.71,15.59a5,5,0,1,1-5,5A5,5,0,0,1,19.71,15.59Z" style="fill: rgb(255, 255, 255); fill-rule: evenodd;"></path></g></g></svg></section></section><section style="width: 140px; margin-top: -40px; box-sizing: border-box;"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 254.17 85.67" xml:space="default" style="display: block;"><g id="图层_2"><g id="图层_1-2"><path d="M16,0A16.28,16.28,0,0,0,0,16.53C0,25.66,16,42,16,42S32,25.66,32,16.53A16.27,16.27,0,0,0,16,0Zm0,22.91a7.72,7.72,0,1,1,7.68-7.72A7.69,7.69,0,0,1,16,22.91Z" style="fill: rgb(255, 216, 96); fill-rule: evenodd;"></path><path d="M17,42S-15.36,88.39,76,68c57.05-12.73,111.36-8.48,89,5-27,16.29,34.67,17.14,89-3" style="fill: none; stroke: rgb(51, 51, 51); stroke-dasharray: 6, 4;"></path></g></g></svg></section></section></section></section><section><p><br></p></section></section>`

</script>

<template>
  <section><section><section style="margin: 10px auto; display: flex; justify-content: center; padding-bottom: 5px; box-sizing: border-box;"><section style="display: flex; flex-direction: column;"><section class="assistant" style="width: 35px; margin-left: auto; box-sizing: border-box;"><img src="https://oss.tccms.cn/1sqnkqGnuBk" draggable="false" class="assistant" style="width: 100%; display: block; vertical-align: baseline; box-sizing: border-box; max-width: 100% !important;"></section><section style="display: flex; flex-direction: column; margin: 0px 20px; z-index: 3;"><section style="font-size: 16px; color: rgb(255, 255, 255); text-align: center; z-index: 4;"><strong>Haha</strong></section><section style="width: 150px; margin: -43px auto 0px; box-sizing: border-box;"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 219 81" xml:space="default" style="display: block;"><g id="图层_2"><g id="图层_1-2"><polygon points="212 9 207 0 18 9 9 10 0 59 18 81 207 81 219 22 211.91 9 212 9" style="fill: rgb(112, 204, 251); fill-rule: evenodd;"></polygon><path d="M13.71,47.59a5,5,0,1,1-5,5A5,5,0,0,1,13.71,47.59Z" style="fill: rgb(255, 255, 255); fill-rule: evenodd;"></path><path d="M16.71,31.59a5,5,0,1,1-5,5A5,5,0,0,1,16.71,31.59Z" style="fill: rgb(255, 255, 255); fill-rule: evenodd;"></path><path d="M19.71,15.59a5,5,0,1,1-5,5A5,5,0,0,1,19.71,15.59Z" style="fill: rgb(255, 255, 255); fill-rule: evenodd;"></path></g></g></svg></section></section><section style="width: 140px; margin-top: -40px; box-sizing: border-box;"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 254.17 85.67" xml:space="default" style="display: block;"><g id="图层_2"><g id="图层_1-2"><path d="M16,0A16.28,16.28,0,0,0,0,16.53C0,25.66,16,42,16,42S32,25.66,32,16.53A16.27,16.27,0,0,0,16,0Zm0,22.91a7.72,7.72,0,1,1,7.68-7.72A7.69,7.69,0,0,1,16,22.91Z" style="fill: rgb(255, 216, 96); fill-rule: evenodd;"></path><path d="M17,42S-15.36,88.39,76,68c57.05-12.73,111.36-8.48,89,5-27,16.29,34.67,17.14,89-3" style="fill: none; stroke: rgb(51, 51, 51); stroke-dasharray: 6, 4;"></path></g></g></svg></section></section></section></section><section><p><br></p></section></section>
  <div v-html="html" />
</template>

至于为什么,看起来是因为 v-html 给你的 svg 元素添加HTML属性时,使用 setAttribute() 方法导致的。该方法会将其属性名称自动转换为全小写形式这样来设置目标元素的 HTML 属性,正好规避掉了你的 viewbox 大小写错误的问题。

楚嘉玉
2024-09-18

将 vue 模板中 svg 的 viewbox 属性修改为 viewBox 即可渲染一致

施飞雨
2024-09-18

在使用 Vue.js 的 v-html 指令时,你确实可能会遇到与直接在模板中编写 HTML 不同的表现。这通常是因为 v-html 会直接渲染原始的 HTML 字符串,而 Vue 模板中的 HTML 会经过 Vue 的编译和虚拟 DOM 的处理。这种差异可能由以下几个原因引起:

  1. CSS 样式作用域:直接在模板中编写的 HTML 会受到组件内部或全局 CSS 的影响,而 v-html 插入的 HTML 可能不会(除非这些样式是全局的或具有足够的选择器优先级来覆盖)。
  2. Vue 的响应性v-html 插入的 HTML 是静态的,它不会响应 Vue 实例的数据变化。而模板中的 HTML 可以包含 Vue 指令(如 v-ifv-for 等),这些指令会根据 Vue 实例的数据变化来动态地更新 DOM。
  3. 安全性:使用 v-html 插入不受信任的 HTML 可能会带来 XSS(跨站脚本攻击)的风险,因为它会执行 HTML 中的 JavaScript 代码。而直接在模板中编写的 HTML 则是安全的,因为 Vue 会对其进行适当的转义。

为了规避这些差异,你可以考虑以下策略:

  • 确保样式的一致性:确保 v-html 插入的 HTML 使用的样式与组件内部或全局样式一致。你可以通过检查 CSS 选择器的优先级和范围来实现这一点。
  • 使用 Vue 组件:如果可能,将需要动态渲染的 HTML 封装成 Vue 组件,并通过 props 传递数据给这些组件。这样可以保持 Vue 的响应性和安全性,并且可以更容易地控制样式和行为。
  • 清理和过滤 HTML:如果你必须从外部源获取 HTML,请确保对其进行清理和过滤,以去除潜在的恶意代码和不必要的标签。你可以使用 DOM 解析库(如 DOMPurify)来清理 HTML。
  • 避免使用 v-html:如果可能,尽量避免使用 v-html。相反,使用 Vue 的数据绑定和指令来动态渲染内容。这不仅可以提高安全性,还可以保持代码的清晰和可维护性。

综上所述,通过确保样式一致性、使用 Vue 组件、清理和过滤 HTML 以及避免使用 v-html,你可以规避 v-html 与直接在模板中编写 HTML 之间的表现差异。

 类似资料:
  • 问题内容: 在JavaScript代码周围使用HTML注释标记仍然有意义吗? 我的意思是 问题答案: HTML注释,即 ,不再需要。它们旨在允许不了解该标记的浏览器正常降级。这些浏览器,例如 不再在野外找到Netscape1.x。因此,再也没有必要在脚本标记中添加HTML注释了。 如果希望HTML验证为XHTML或XML,则可能要使用注释掉的CDATA标记。 这样做的原因是为了确保你,,,和这是你

  • 菜鸟一个,觉得vue那种语法真的是太棒了

  • 我想问一下我如何才能在一个页面中使用相同的提交2个html表单。我希望对这两个表单都有相同的操作,从而使用相同的servlet来处理Reuqest。

  • 需求: 后端会返回一个各种内容组合的数据到前端。前端需要根据对应的名称生成各种展示样式 例: 上面有三个简单的示例(/业务场景比这个多): name: 需要直接输出即可, address: 需要按某种格式输出, capital: 需要每个投资人一行. 其中capital.name要增加连接 现代码: printChangeItem方法负责将英文键换成中文. printAdapterExpr方法根据

  • 调用大模型采用流式方式输出内容,并且输出的内容有MD和普通的HTML格式,应该如何渲染的前端页面呢? 我是用jquery中的html()当时内容并没有按照返回的格式显示出来

  • 这是我的模板: 这是我的视图模板: 我得到的内容是html,我想在视图中显示,但我得到的只是原始html代码。如何呈现HTML?