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

无头WordPress+Nuxt:拆分HTML与Shortcode为对象数组方案咨询

解决方案:用正则拆分内容 + 动态组件渲染

对于结构简单的WordPress短代码(shortcode),正则是当前场景下的最优方案——轻量、无额外依赖,完全适配你的需求,没必要引入复杂的HTML解析库。下面是具体实现步骤:

1. 编写正则与内容拆分函数

先写一个能匹配短代码的正则,覆盖自闭合([my-shortcode attr="val"])和闭合式([my-shortcode]内部内容[/my-shortcode])两种简单结构,再通过循环将HTML内容拆分为目标数组:

function parseContentWithShortcodes(htmlContent) {
  const parts = [];
  // 匹配短代码的正则:捕获标签名、属性、内部内容(可选),忽略大小写
  const shortcodeRegex = /\[([a-zA-Z0-9_-]+)(?:\s+([a-zA-Z0-9_-]+="[^"]*")*)*\s*\](.*?)(?:\[\/\1\])?/gsi;
  let lastIndex = 0;
  let match;

  while ((match = shortcodeRegex.exec(htmlContent)) !== null) {
    // 提取短代码之前的普通HTML内容
    if (match.index > lastIndex) {
      parts.push({
        type: 'html',
        content: htmlContent.slice(lastIndex, match.index)
      });
    }

    const [_, tagName, attrStr, innerContent] = match;
    // 解析短代码的属性键值对
    const attrs = {};
    if (attrStr) {
      const attrMatchRegex = /([a-zA-Z0-9_-]+)="([^"]*)"/g;
      let attrMatch;
      while ((attrMatch = attrMatchRegex.exec(attrStr)) !== null) {
        attrs[attrMatch[1]] = attrMatch[2];
      }
    }

    // 推入短代码对象
    parts.push({
      type: 'shortcode',
      content: {
        tag: tagName, // 短代码标签名,对应Vue组件名
        attrs,
        inner: innerContent || ''
      }
    });

    lastIndex = shortcodeRegex.lastIndex;
  }

  // 处理剩余的HTML内容
  if (lastIndex < htmlContent.length) {
    parts.push({
      type: 'html',
      content: htmlContent.slice(lastIndex)
    });
  }

  return parts;
}

2. 在Nuxt组件中渲染拆分后的内容

将拆分后的数组循环渲染,普通HTML用v-html输出,短代码用Vue动态组件匹配对应组件:

<template>
  <div class="article-content">
    <template v-for="(item, idx) in parsedContent" :key="idx">
      <!-- 渲染普通HTML -->
      <span v-if="item.type === 'html'" v-html="item.content"></span>
      <!-- 渲染短代码对应的Vue组件 -->
      <component
        v-else
        :is="resolveComponent(item.content.tag)"
        v-bind="item.content.attrs"
      >
        {{ item.content.inner }}
      </component>
    </template>
  </div>
</template>

<script setup>
import { computed } from 'vue';
// 导入你的短代码组件,或者用Nuxt自动组件导入
import ProductCard from './components/ProductCard.vue';
import BannerBox from './components/BannerBox.vue';

const props = defineProps({
  rawContent: {
    type: String,
    required: true
  }
});

// 注册组件,确保短代码标签名与组件名对应(支持kebab-case)
const components = {
  'product-card': ProductCard,
  'banner-box': BannerBox
};

// 解析内容为目标数组
const parsedContent = computed(() => {
  return parseContentWithShortcodes(props.rawContent);
});

// 匹配组件(处理标签名大小写/格式问题)
const resolveComponent = (tag) => {
  return components[tag.toLowerCase()] || 'span'; // 找不到组件时用span兜底
};
</script>

关键注意事项

  • 正则可按需调整:如果不需要支持闭合式短代码,去掉(.*?)(?:\[\/\1\])?部分即可;如果属性不需要引号,修改属性匹配规则。
  • 组件名要对应:WordPress短代码是[product-card],Vue组件就注册为product-card,Vue原生支持kebab-case组件名。
  • 性能优化:如果文章内容不会频繁变更,可把解析后的结果缓存到Vuex/Pinia或localStorage,避免重复执行正则解析。
  • 边界处理:给无法匹配的短代码设置兜底组件(比如示例中的span),避免渲染异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 20:01:01