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

如何在Vue/Nuxt中动态渲染组件,复刻Next.js的BlockManager逻辑?

Nuxt.js 动态区块渲染完整实现方案

1. 前置路由配置(对应Next.js的catch-all路由)

  • Nuxt2 路由规则:在pages/目录下创建_.vue文件捕获所有slug
  • Nuxt3 路由规则:在pages/目录下创建[...slug].vue文件捕获所有slug
  • 页面中通过useRoute()(Nuxt3)或$route(Nuxt2)获取slug参数,请求API拿到页面blocks数据,传入BlockManager组件即可。

2. BlockManager 核心实现(Vue/Nuxt对应React动态渲染逻辑)

Vue 提供原生的动态组件语法<component :is="xxx",完全可以对标你React里的动态组件渲染逻辑,以下是完整的单文件组件实现:

Nuxt3 版本示例

<!-- components/BlockManager.vue -->
<template>
  <div>
    <component
      v-for="(block, index) in blocks"
      :key="`index-${index}`"
      :is="getBlockComponent(block.__component)"
      v-bind="getBlockProps(block)"
    />
  </div>
</template>

<script setup>
// 手动导入区块组件(如果不用Nuxt自动导入的话)
import Hero from '~/components/blocks/Hero.vue'
import Pricing from '~/components/blocks/Pricing.vue'

// 组件映射表,替代原来的switch逻辑,更易维护
const componentMap = {
  'blocks.hero': Hero,
  'blocks.prices': Pricing
}

// 入参声明
const props = defineProps({
  blocks: {
    type: Array,
    default: () => []
  }
})

// 获取对应组件
const getBlockComponent = (componentName) => {
  return componentMap[componentName] || null
}

// 剥离__component属性,返回组件需要的props
const getBlockProps = (block) => {
  const { __component, ...rest } = block
  return rest
}
</script>

自动注册简化方案(无需手动导入组件)

Nuxt 默认开启组件自动导入功能,你只需要把所有区块组件放在components/blocks/目录下,命名和__component字段对应即可,比如blocks.hero对应components/blocks/Hero.vue,上述代码可以进一步简化,不需要手动import和维护映射表:

<script setup>
const props = defineProps({
  blocks: {
    type: Array,
    default: () => []
  }
})

// 直接把__component字段转换为Nuxt自动注册的组件名即可,命名转换规则可根据自己的实际命名调整
const getBlockComponent = (componentName) => {
  // 示例规则:把blocks.hero转为BlocksHero,匹配自动导入的组件名
  return componentName.split('.').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join('')
}

const getBlockProps = (block) => {
  const { __component, ...rest } = block
  return rest
}
</script>

3. 核心逻辑对应说明

你原代码里的return Block ? <Block key={index-${index}} {...rest}/> : null;,在Vue里的等价逻辑完全对齐:

  • :is="getBlockComponent(block.__component) 对应获取要渲染的组件,无匹配组件返回null时不会渲染任何内容
  • v-bind="getBlockProps(block)" 对应{...rest}透传所有组件所需属性
  • :key="index-${index}`` 和React的key作用完全一致,用于列表渲染的Diff优化

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 23:57:05