【问题标题】:Vue 3 replacing the HTML tags where v-html is called with the provided HTMLVue 3 用提供的 HTML 替换调用 v-html 的 HTML 标签
【发布时间】:2021-11-19 16:58:20
【问题描述】:

这是关于 Vite 的 Vue 3 应用程序,而不是 webpack。

目前,正如您在this issue on vite's issue page 中看到的那样,vite 没有一种方便的方法来内联 SVG,而无需使用外部插件。然而,Vite 确实如此,support importing files as raw text strings。因此,我有一个想法来使用此功能并通过将原始 SVG 字符串传递到元素的 v-html 来内联 SVG。

实际上效果很好,SVG 可以按预期显示在页面上,并且我可以进行通常的 CSS 转换(像这样内联它们的全部目的),但它并不完美。就目前而言,接收v-html 指令的元素只是将提供的 HTML 嵌套为子元素。例如,如果我执行<span v-html="svgRaw" />,最终的 HTML 会是这样的

<span>
  <svg>
    <!-- SVG attributes go here -->
  </svg>
</span>

我有什么办法可以将声明v-html 的父元素替换为传递给它的顶级元素吗?在上面的例子中,这意味着&lt;span&gt; 只是变成了&lt;svg&gt;

编辑:

感谢 tony19 提到自定义指令。

我的最终结果是这样的:

// main.ts
import { createApp } from "vue";
import App from "./App.vue";

const app = createApp(App);

app.directive("inline", (element) => {
  element.replaceWith(...element.children);
});

app.mount("#app");

然后,在组件中,我只需使用指令&lt;svg v-html="svgRaw" v-inline /&gt;,效果很好!

【问题讨论】:

    标签: vue.js vuejs3 vite


    【解决方案1】:

    您可以创建一个custom directive,将包装器元素替换为其内容:

    1. 使用app.directive() 创建一个全局指令,命名为v-hoist

      // main.js
      import { createApp } from 'vue'
      import App from './App.vue'
      
      createApp(App)
        .directive('hoist', el => {
          if (el.tagName === 'TEMPLATE') {
            el.replaceWith(el.content)
          } else {
            el.replaceWith(...el.children)
          }
        })
        .mount('#app')
      
    2. 在您的组件中,在 v-html 包装元素上包含 v-hoist(也适用于 Vue 3 中的 &lt;template&gt;):

      <svg v-html="svgRaw" v-hoist />
      <!-- OR -->
      <template v-html="svgRaw" v-hoist />
      

    demo

    【讨论】:

      【解决方案2】:

      来自 Vue2。我认为这仍然有效:
      你可以使用特殊的 Vue 标签 template,而不是 span

      <template v-html="svgRaw" />
      

      这不会将&lt;template /&gt; 呈现为标签本身,而是在没有父元素的情况下呈现v-html 中给出的元素。

      【讨论】:

      • 我在 Vue2 项目中使用它,它在那里工作......?您链接的 Vue2 示例没有任何内容。我仍在保留这个答案,以便人们可以看到它是错误的。
      • 我最初尝试过这个,但在这种情况下没有任何记录。 Evan 在 Github 问题中提到(我目前找不到)模板不支持任何指令
      • @PeterKrebs 是的,Vue 2 链接没有“任何东西”(即,不会为 &lt;template v-html="html"&gt; 呈现任何内容),因为在 Vue 2 中通常不支持在 &lt;template&gt; 上使用 v-html。有趣的是它对您的项目有任何影响。可以分享一个链接吗?
      • 这不是一个公开的项目,对不起。不过,Vue2 文档有一个 using template with v-if 的示例。
      猜你喜欢
      • 2021-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-19
      相关资源
      最近更新 更多