HTML 包含 Vue 组件的字符串的 Nuxt 渲染函数

Nuxt render function for a string of HTML that contains Vue components

我正在尝试为 Nuxt 解决这个问题

WIP 的代码和框不工作:https://codesandbox.io/s/zw26v3940m

好的,所以我将 WordPress 作为 CMS,它正在输出一堆 HTML。 HTML 的示例如下所示:

'<h2>A heading tag</h2>
<site-banner image="{}" id="123">Slot text here</site-banner>
<p>some text</p>'

请注意,它包含一个 Vue 组件 <site-banner>,上面有一些道具(image 道具是一个 JSON 对象,为了简洁我省略了)。该组件已在全球注册。

我有一个我们编写的组件,名为 <wp-content>,它在 Vue 中运行良好,但在 Nuxt 中不起作用。请注意两个渲染函数,一个用于 Vue,另一个用于 Nuxt(显然这是为了举例,我不会同时使用)。

export default {
    props: {
        html: {
            type: String,
            default: ""
        }
    },
    render(h, context) {
        // Worked great in Vue
        return h({ template: this.html })
    }      
    render(createElement, context) {
        // Kind of works in Nuxt, but doesn't render Vue components at all
        return createElement("div", { domProps: { innerHTML: this.html } })
    } 
}

所以最后一个渲染函数在 Nuxt 中工作,除了它不会实际渲染 this.html 中的 Vue 组件,它只是将它们作为 HTML.

放在页面上

那么我如何在 Nuxt 中执行此操作?我想从服务器获取一串 HTML ,并将其呈现在页面上,并将任何已注册的 Vue 组件转换为适当的成熟 Vue 组件。基本上有点"VueifyThis(html)"工厂。

如果您使用 v-html 指令来呈现 html?

喜欢:

<div v-html="html"></div>

我认为它会完成工作。

我对你的codesandbox做了一些修改。现在似乎工作 https://codesandbox.io/s/q9wl8ry6q9

我更改的内容无效:

  1. 模板在当前版本的 Vue 中只能有一个根元素
  2. v-bind只接受变量,但你传入一个字符串。

这是codesandbox上的解决方案:https://codesandbox.io/s/wpcontent-j43sp

要点是将动态组件包装在 dynamicComponent() 模板中的 <div>(因此是 HTML 标记)中,因为它只能有一个根元素,并且因为它来自 Wordpress,源字符串本身可以有任意数量的顶级元素。

并且必须导入 WpContent 组件。

感谢 Nuxt 团队的 Jonas Galvez oTechie

export default {
  props: {
    html: {
      type: String,
      default: ""
    }
  },
  render(h) {
    return h({
      template: `<div>${this.html}</div>`
    });
  }
};

然后在您的 nuxt.config.js 文件中:

    build: {
        extend(config, ctx) {
            // Include the compiler version of Vue so that <component-name> works
            config.resolve.alias["vue$"] = "vue/dist/vue.esm.js"
        }
    }

这就是我用 Nuxt 3 做的:

<script setup lang="ts">
import { h } from 'vue';

const props = defineProps<{
  class: string;
  HTML: string
}>();
const VNode = () => h('div', { class: props.class, innerHTML: props.HTML })
</script>
<template>
  <VNode />
</template>

不需要更新 nuxt.config.ts
希望对大家有所帮助。