You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nuxt 3与Vue项目中文章嵌入组件及标签嵌套问题求助

在Nuxt 3/Vue中动态渲染文章内组件的解决方法

方案一:解析内容为Vue渲染节点(推荐)

  • 核心思路:放弃直接用v-html渲染含自定义组件的HTML,先把文章内容拆分为普通文本片段和组件配置,再通过Vue的<component>标签动态渲染,彻底避免浏览器自动修正标签的问题。
  • 具体步骤:
    1. 编写解析函数,将特殊标签转换为组件配置:
      // 可根据实际需求扩展解析规则
      function parseArticle(content) {
        // 替换#GALLERY#为基础组件配置
        content = content.replace(/#GALLERY#/g, JSON.stringify({
          type: 'v-gallery'
        }));
        // 解析带属性的<v-gallery :id="1"/>标签
        content = content.replace(/<v-gallery :id="(\d+)"/>/g, (_, id) => {
          return JSON.stringify({
            type: 'v-gallery',
            props: { id: parseInt(id) }
          });
        });
        // 拆分内容为文本和组件节点数组
        return content.split(/(\{.*?\})/).map(item => {
          try {
            const parsed = JSON.parse(item);
            return { isComponent: true, ...parsed };
          } catch {
            return { isComponent: false, html: item };
          }
        });
      }
      
    2. 在组件中动态渲染解析结果:
      <template>
        <div class="article-content">
          <template v-for="(item, idx) in parsedContent" :key="idx">
            <component v-if="item.isComponent" :is="item.type" v-bind="item.props" />
            <span v-else v-html="item.html"></span>
          </template>
        </div>
      </template>
      
      <script setup>
      import VGallery from '~/components/VGallery.vue';
      const props = defineProps(['articleContent']);
      const parsedContent = parseArticle(props.articleContent);
      </script>
      
  • 优势:完美支持嵌套结构,组件能正常响应Vue生命周期,无标签错位问题。

方案二:自定义指令手动挂载组件

  • 核心思路:先用v-html渲染文本,再通过自定义指令查找页面中的自定义组件标签,手动创建组件实例并挂载。
  • 具体步骤:
    1. 在Nuxt插件中注册全局指令:
      // plugins/mount-components.js
      import { defineNuxtPlugin, createApp } from '#app';
      import VGallery from '~/components/VGallery.vue';
      
      export default defineNuxtPlugin(nuxtApp => {
        nuxtApp.vueApp.directive('mount-components', {
          mounted(el) {
            // 查找所有自定义组件标签(建议用非标准标签名,比如<x-gallery>避免浏览器自动修正)
            const galleryTags = el.querySelectorAll('x-gallery');
            galleryTags.forEach(tag => {
              const id = tag.getAttribute('data-id');
              // 创建并挂载组件
              const app = createApp(VGallery, { id: parseInt(id) });
              app.mount(tag);
            });
          }
        });
      });
      
    2. 页面中使用:
      <template>
        <!-- 先把文章中的<v-gallery :id="1"/>替换为<x-gallery data-id="1"/>再传递 -->
        <div class="article-content" v-html="processedContent" v-mount-components></div>
      </template>
      
  • 注意:需将原自定义组件标签替换为浏览器不会自动修正的非标准标签(如前缀加x-),避免嵌套结构被破坏。

方案三:使用第三方模板渲染库

  • 直接借助成熟库处理含Vue组件的模板字符串,无需手动解析:
    1. 安装依赖:
      npm install vue-runtime-template
      
    2. 组件中使用:
      <template>
        <div class="article-content">
          <runtime-template :template="articleContent" :components="{ VGallery }" />
        </div>
      </template>
      
      <script setup>
      import RuntimeTemplate from 'vue-runtime-template';
      import VGallery from '~/components/VGallery.vue';
      const props = defineProps(['articleContent']);
      </script>
      
  • 优势:开箱即用,自动处理嵌套结构和组件属性,适合快速开发场景。

内容的提问来源于stack exchange,提问作者nup

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 16:15:55