页面构建器设计Skill design-page-builder

这个技能用于设计和实现模块化的页面构建系统,支持组件化、槽位布局和块状编辑,适用于前端框架如 Blazor、React、Vue 等。它帮助开发者快速搭建内容管理系统的页面结构,提升编辑体验和开发效率。关键词:模块化页面构建、组件设计、槽位布局、块状编辑、前端开发、CMS。

前端开发 0 次安装 2 次浏览 更新于 3/11/2026

name: design-page-builder description: 设计一个模块化的页面组合系统,包含组件、槽位和布局区域。支持基于块的编辑。 argument-hint: [–pattern components|slots|hybrid] [–framework blazor|react|vue] allowed-tools: Read, Glob, Grep, Task, Skill, AskUserQuestion

设计页面构建器命令

设计一个用于块状内容编辑的模块化页面组合系统。

使用方法

/cms:design-page-builder --pattern components
/cms:design-page-builder --pattern slots --framework blazor
/cms:design-page-builder --pattern hybrid

组合模式

  • components: 可重用的组件库
  • slots: 基于命名槽位的布局
  • hybrid: 基于槽位模板内的组件

工作流程

步骤 1: 解析参数

从命令中提取模式类型和框架。

步骤 2: 收集需求

使用 AskUserQuestion 来理解:

  • 编辑需要什么程度的灵活性?
  • 是否有特定的布局要求?
  • 组件是否应该可嵌套?
  • 需要什么预览功能?

步骤 3: 调用技能

调用相关技能:

  • page-structure-design - 页面模板
  • content-type-modeling - 组件内容类型

步骤 4: 设计组件库

组件定义:

components:
  # 布局组件
  - name: Section
    category: Layout
    description: 全宽区域,带有背景选项
    props:
      background_color: string
      background_image: MediaField
      padding: enum[none, small, medium, large]
      width: enum[full, contained, narrow]
    slots:
      - name: content
        allowed: [Hero, Grid, TextBlock, ImageGallery]

  - name: Grid
    category: Layout
    description: 响应式网格容器
    props:
      columns: enum[2, 3, 4]
      gap: enum[small, medium, large]
      mobile_stack: boolean
    slots:
      - name: items
        allowed: [Card, Feature, Testimonial]
        min: 1
        max: 12

  # 内容组件
  - name: Hero
    category: Content
    description: 带有标题和 CTA 的英雄横幅
    props:
      headline: TextField
      subheadline: TextField
      background_image: MediaField
      background_video: MediaField
      overlay_opacity: number
      text_alignment: enum[left, center, right]
      height: enum[small, medium, large, full]
    slots:
      - name: cta
        allowed: [Button, ButtonGroup]
        max: 1

  - name: TextBlock
    category: Content
    description: 富文本内容块
    props:
      content: HtmlField
      alignment: enum[left, center, right, justify]

  - name: Card
    category: Content
    description: 带有图像和文本的内容卡片
    props:
      image: MediaField
      title: TextField
      description: TextField
      link: LinkField

  - name: ImageGallery
    category: Media
    description: 响应式图像画廊
    props:
      images: MediaField[]
      layout: enum[grid, masonry, carousel]
      columns: number
      lightbox: boolean

  - name: Testimonial
    category: Social Proof
    description: 客户推荐语
    props:
      quote: TextField
      author: TextField
      role: TextField
      avatar: MediaField
      rating: number

  - name: CallToAction
    category: Conversion
    description: 带有表单或按钮的 CTA 部分
    props:
      headline: TextField
      description: TextField
      button_text: TextField
      button_url: LinkField
      form: ContentPickerField[Form]

步骤 5: 设计页面模板

带有槽位的模板:

templates:
  - name: Homepage
    description: 主要登录页面模板
    slots:
      - name: hero
        label: 英雄区域
        allowed: [Hero]
        required: true

      - name: featured
        label: 特色内容
        allowed: [Section, Grid]
        max: 3

      - name: main
        label: 主要内容
        allowed: [Section, TextBlock, ImageGallery, Grid]

      - name: testimonials
        label: 推荐语
        allowed: [Testimonial, Grid]

      - name: cta
        label: 行动号召
        allowed: [CallToAction]

  - name: ProductLanding
    description: 产品登录页面
    slots:
      - name: hero
        allowed: [Hero]
        required: true

      - name: features
        allowed: [Grid, Section]

      - name: pricing
        allowed: [PricingTable]

      - name: faq
        allowed: [Accordion]

      - name: cta
        allowed: [CallToAction]

  - name: BlogPost
    description: 博客文章模板
    slots:
      - name: header
        allowed: [ArticleHeader]
        required: true

      - name: content
        allowed: [TextBlock, ImageGallery, CodeBlock, Quote]

      - name: author
        allowed: [AuthorBio]

      - name: related
        allowed: [RelatedPosts]

步骤 6: 生成数据模型

EF Core 模型:

public class Page
{
    public Guid Id { get; set; }
    public string Title { get; set; }
    public string Slug { get; set; }
    public string TemplateId { get; set; }
    public PageStatus Status { get; set; }

    // JSON 列用于灵活内容
    public PageContent Content { get; set; }
}

[Owned]
public class PageContent
{
    public Dictionary<string, List<ComponentInstance>> Slots { get; set; }
}

[Owned]
public class ComponentInstance
{
    public string Id { get; set; }
    public string ComponentType { get; set; }
    public Dictionary<string, object> Props { get; set; }
    public Dictionary<string, List<ComponentInstance>> NestedSlots { get; set; }
}

// DbContext 配置
modelBuilder.Entity<Page>()
    .OwnsOne(p => p.Content, cb =>
    {
        cb.ToJson();
    });

步骤 7: 生成 Blazor 组件(如果框架=blazor)

组件渲染器:

@* ComponentRenderer.razor *@
@inject IComponentRegistry Registry

@foreach (var component in Components)
{
    <DynamicComponent
        Type="@Registry.GetComponentType(component.ComponentType)"
        Parameters="@GetParameters(component)" />
}

@code {
    [Parameter] public List<ComponentInstance> Components { get; set; }

    private Dictionary<string, object> GetParameters(ComponentInstance instance)
    {
        var parameters = new Dictionary<string, object>(instance.Props);

        if (instance.NestedSlots?.Any() == true)
        {
            parameters["NestedSlots"] = instance.NestedSlots;
        }

        return parameters;
    }
}

英雄组件:

@* Components/Hero.razor *@
<section class="hero @HeightClass" style="@BackgroundStyle">
    @if (OverlayOpacity > 0)
    {
        <div class="hero-overlay" style="opacity: @OverlayOpacity"></div>
    }

    <div class="hero-content @AlignmentClass">
        <h1>@Headline</h1>
        @if (!string.IsNullOrEmpty(Subheadline))
        {
            <p class="hero-subheadline">@Subheadline</p>
        }

        @if (NestedSlots?.ContainsKey("cta") == true)
        {
            <div class="hero-cta">
                <ComponentRenderer Components="@NestedSlots["cta"]" />
            </div>
        }
    </div>
</section>

@code {
    [Parameter] public string Headline { get; set; }
    [Parameter] public string Subheadline { get; set; }
    [Parameter] public string BackgroundImage { get; set; }
    [Parameter] public decimal OverlayOpacity { get; set; }
    [Parameter] public string TextAlignment { get; set; } = "center";
    [Parameter] public string Height { get; set; } = "medium";
    [Parameter] public Dictionary<string, List<ComponentInstance>> NestedSlots { get; set; }

    private string HeightClass => $"hero--{Height}";
    private string AlignmentClass => $"text-{TextAlignment}";
    private string BackgroundStyle =>
        !string.IsNullOrEmpty(BackgroundImage)
            ? $"background-image: url({BackgroundImage})"
            : "";
}

编辑器体验

设计页面构建器编辑器:

editor:
  features:
    - drag_drop: true
    - inline_editing: true
    - live_preview: true
    - responsive_preview: [mobile, tablet, desktop]
    - undo_redo: true
    - component_search: true
    - keyboard_shortcuts: true

  sidebar:
    - components_panel
    - settings_panel
    - layers_panel

  toolbar:
    - save
    - preview
    - publish
    - device_toggle
    - undo
    - redo

相关技能

  • page-structure-design - 页面模板
  • content-type-modeling - 组件类型
  • dynamic-schema-design - JSON 列存储