@ bagelink/ blox (英语)
Blox 提供 Vue 组件、路由、预览和静态生成 贝斯林克网站.
安装
pnpm add @bagelink/blox @bagelink/vue vue vue-router
支助科
每个 Blox 网站必须从客户端导入这两个样式表一次
条目(src/main.ts),在项目样式之前:
import '@bagelink/vue/styles/core.css'
import '@bagelink/blox/style.css'
import './styles/main.css'
使用 @bagelink/vue/styles/admin.css 改为 core.css 仅供管理员使用
需要 Bagel 字体包的应用程序.
不导入 @bagelink/vue/dist/style.css 或者说
@bagelink/blox/dist/style.css;这些内部路径仅用于
现有项目。 在本地开发中导入相同的条目, CI so a
源化名无法隐藏软件包导出问题 .
制作网站设置
// main.ts
import { createBloxApp } from '@bagelink/blox'
import { BagelVue } from '@bagelink/vue'
import '@bagelink/vue/styles/core.css'
import '@bagelink/blox/style.css'
import App from './App.vue'
import router from './router'
const blocks = import.meta.glob('./components/blocks/*.vue', { eager: true })
createBloxApp({
rootComponent: App,
router,
modules: blocks,
websiteName: 'my-site',
store: 'my-site',
locale: 'en',
supportedLocales: ['en'],
plugins: [BagelVue],
navigation: 'document',
})
// main.server.ts
import { createBloxSSREntry } from '@bagelink/blox/ssg'
import { BagelVue } from '@bagelink/vue'
import App from './App.vue'
import { createRouter } from './router'
const blocks = import.meta.glob('./components/blocks/*.vue', { eager: true })
export const { render, prefetchResolve } = createBloxSSREntry({
rootComponent: App,
createRouter,
modules: blocks,
websiteName: 'my-site',
store: 'my-site',
locale: 'en',
supportedLocales: ['en'],
plugins: [BagelVue],
})
客户端水合物直接交接了HTML. 组件可以使用普通 Vue
原始人包括: Suspense, (中文(简体) ), Teleport皮尼亚,和 onServerPrefetch。 。 。 .
使用 useData(key, loader) 用于必须存在于静态 HTML 和
水分有效载荷。 不要安装抓取或 Axios 缓存截取器 .
Blox拥有预览路线和一个被命名为CMS倒置路线. 消费者路由器 应只申报应用软件的路线和方向.
有自定义组件
import { createBlox, createComponentConfig, ButtonConfig } from '@bagelink/blox'
import MyHeroSection from './components/MyHeroSection.vue'
const MyHeroConfig = createComponentConfig({
id: 'MyHero',
label: 'Hero Section',
icon: 'hero_section',
component: MyHeroSection,
content: [
{
type: 'text',
key: 'title',
label: 'Hero Title',
defaultValue: 'Welcome!',
},
],
})
const blox = createBlox()
blox.registerComponents([ButtonConfig, MyHeroConfig]).registerRoutes(router)
app.use(blox)
可用内置组件配置
导入这些配置以注册内置组件 :
ButtonConfig- 自定义按钮/链接TextConfig- 内容丰富TitleConfig- 标题带有可选字幕ImageConfig- 反应图像SpacerConfig- 垂直间距ContainerConfig- 最大宽度的内容容器
更多实例见 SETUP EXAMPLE.md (英语)。 。 。 .
低级别设置
createBlox() 可供编辑和专门嵌入的
造物师. 新制作网站应使用 createBloxApp() 财务报告和审定财务报表
createBloxSSREntry() 因此客户端和服务器组装不能漂移.
1. 登记册基础部分
import { createApp } from 'vue'
import { registerBaseComponents } from '@bagelink/blox'
const app = createApp(App)
// Register all base components
registerBaseComponents(app)
app.mount('#app')
2. 使用演示页部分
<template>
<RenderPage :page-data="pageData" />
</template>
<script setup lang="ts">
import { RenderPage } from '@bagelink/blox'
const pageData = {
components: [...],
pageSettings: {...}
}
</script>
3. 对页面构建器使用外部预览
<template>
<ExternalPreview :origin="editorOrigin" />
</template>
<script setup lang="ts">
import { ExternalPreview } from '@bagelink/blox'
const editorOrigin = 'https://your-editor.com'
</script>
核心概念
书记官处
注册您的自定义组件以便在页面构建器中提供 :
import { registerComponent, registerComponents } from '@bagelink/blox'
import MyButton from './MyButton.vue'
// Register a single component
registerComponent('Button', MyButton)
// Or register multiple components at once
registerComponents({
Button: MyButton,
Hero: MyHero,
Text: MyText,
})
通信系统
Blox 包括一个内置的通信系统,用于构建器和预览之间的协调:
import { createCommunicationBridge } from '@bagelink/blox'
// Create a communication bridge
const bridge = createCommunicationBridge({
origin: 'https://editor.com',
targetWindow: window.parent,
})
// Listen for messages
bridge.on('update', ({ data }) => {
console.log('Received update:', data)
})
// Send messages
bridge.send('ready', { components: ['Button', 'Hero'] })
造型公用事业
使用内置的样式工具来应用一致的样式 :
import { generateBlockStyles, getResponsiveClasses } from '@bagelink/blox'
const styles = generateBlockStyles(blockData, false)
const classes = getResponsiveClasses(blockData)
基本组件
图书馆包括这些预建组件:
- 按钮 - 有变体的自定义按钮
- 集装箱 - 间隔布局容器
- 图像 - 反应图像组件
- 空间器 - 纵向/横向间隔
- 文本 - 内容丰富
- 标题 - 标题部分
API 参考
书记官处 API
registerComponent(type: string, component: ComponentConstructor)
注册单个组件.
import { registerComponent } from '@bagelink/blox'
import MyButton from './MyButton.vue'
registerComponent('Button', MyButton)
参数:
type- 块类型标识符(例如:"按钮","英雄")component- Vue 组件构建器或自动同步导入
registerComponents(components: ComponentRegistry)
立即注册多个组件 .
import { registerComponents } from '@bagelink/blox'
registerComponents({
Button: MyButton,
Hero: MyHero,
Text: MyText,
})
参数:
components- 对象映射类型名称到组件
getComponent(type: string): ComponentConstructor | undefined
按类型获取注册组件 .
const ButtonComponent = getComponent('Button')
hasComponent(type: string): boolean
检查是否注册了组件类型 .
if (hasComponent('Button')) {
// Button is registered
}
getAllComponents(): ComponentRegistry
获取所有注册组件 .
const allComponents = getAllComponents()
unregisterComponent(type: string)
从登记册中删除一个组件.
unregisterComponent('Button')
clearRegistry()
删除所有已注册的组件 .
clearRegistry()
getRegisteredTypes(): string[]
获取所有已注册类型名称的阵列 .
const types = getRegisteredTypes()
// ['Button', 'Hero', 'Text']
createNamespacedRegistry(namespace: string)
为多租户方案创建命名空间登记册.
const siteA = createNamespacedRegistry('site-a')
siteA.register('Button', ButtonA)
const siteB = createNamespacedRegistry('site-b')
siteB.register('Button', ButtonB)
回返情况: 有方法的对象 :
register(type, component)- 登记为命名空间get(type)- 从命名空间得到getAll()- 从命名空间得到所有
API 通讯
createCommunicationBridge(config: CommunicationConfig): CommunicationBridge
为Message后通信创建通信桥.
import { createCommunicationBridge } from '@bagelink/blox'
const bridge = createCommunicationBridge({
origin: 'https://editor.com',
targetWindow: window.parent,
})
参数:
config.origin- 允许来源(字符串或“*”)config.targetWindow- 目标窗口(默认:窗口.parent)config.onMessage- 可选全球信息处理器
CommunicationBridge.on(type: MessageType, handler: MessageHandler): () => void
注册处理邮件者 .
const unsubscribe = bridge.on('update', ({ data }) => {
console.log('Received update:', data)
})
// Later: unsubscribe()
参数:
type- 所有信件的邮件类型或“ * ”handler- 处理器功能
回返情况: 取消订阅函数
CommunicationBridge.off(type: MessageType, handler: MessageHandler)
未注册消息处理器 .
bridge.off('update', myHandler)
CommunicationBridge.send(type: MessageType, message?: any, data?: any)
向目标窗口发送信息 .
bridge.send('focus', 'block-123')
bridge.send('update', null, { components: [...] })
参数:
type- 信件类型message- 可选消息有效载荷data- 可选数据有效载荷
CommunicationBridge.destroy()
清净取出一切听者.
bridge.destroy()
sendMessage(type, message?, targetWindow?, origin?)
发送一次性信息而不创建桥梁.
import { sendMessage } from '@bagelink/blox'
sendMessage('ready', { components: ['Button', 'Hero'] })
渲染器 API
initializePage(pageData: PageData): Promise<void>
初始化包含所有设置和资产的页面.
import { initializePage } from '@bagelink/blox'
await initializePage(pageData)
它会做什么:
- 喷射响应CSS
- 应用页面设置
- 装入谷歌字体
- 输入自定义代码
injectResponsiveCSS()
注入响应CSS系统.
import { injectResponsiveCSS } from '@bagelink/blox'
injectResponsiveCSS()
injectCode(code: string | undefined, target: 'head' | 'body')
将自定义代码输入到头部或正文中.
injectCode('<script>console.log("Hello")</script>', 'head')
loadGoogleFont(fontName: string): Promise<void>
装入谷歌字体 .
await loadGoogleFont('Roboto')
loadComponentFonts(components: ComponentData[]): Promise<void>
装入组件中使用的所有字体 .
await loadComponentFonts(pageData.components)
applyGlobalFont(fontName: string)
将字体全局应用到页面中 .
applyGlobalFont('Inter')
applyPageSettings(pageData: PageData)
对文档应用所有页面设置.
applyPageSettings(pageData)
样式 API
generateBlockStyles(data: Record<string, any>, isMobile?: boolean): Record<string, string>
从块数据生成 CSS 样式 .
import { generateBlockStyles } from '@bagelink/blox'
const styles = generateBlockStyles(blockData, false)
// { 'margin-top': '2rem', 'padding': '1rem', ... }
参数:
data- 块数据对象isMobile- 是否使用移动覆盖( 默认: 虚假)
回返情况: CSS 样式对象
getResponsiveClasses(data: Record<string, any>): string[]
获得响应的CSS课程 一个街区.
const classes = getResponsiveClasses(blockData)
// ['blox-block', 'responsive-colors', 'full-width-mobile']
getResponsiveCSS(): string
得到响应的CSS注射.
const css = getResponsiveCSS()
常态化器 API
normalizeComponentData(data: Record<string, any>): Record<string, any>
规范组件数据(转换字符串布尔、数字等).
import { normalizeComponentData } from '@bagelink/blox'
const normalized = normalizeComponentData({
width: '800',
fullWidth: 'true',
title: 'Hello',
})
// { width: 800, fullWidth: true, title: 'Hello' }
deepClone<T>(obj: T): T
深克隆一个对象 .
const cloned = deepClone(originalData)
deepMerge(target: any, source: any): any
深度合并两个对象.
const merged = deepMerge(defaults, customSettings)
构成部分
外部审查
为外部站点预览组件.
<ExternalPreview :origin="editorOrigin" :initial-page-data="pageData" />
道具 :
origin?: string- 允许编辑器来源( 默认: '*' )initialPageData?: PageData- 可选初始页数据
活动 : 通过Message与这些消息类型进行通信:
ready- 预览准备好后发送focus- 当块被聚焦时发送highlight- 当块突出时发送
渲染页
生产成分.
<RenderPage :page-data="pageData" :mobile-breakpoint="910" />
道具 :
pageData: PageData- 说吧 需求 要提供的页面数据mobileBreakpoint?: number- 移动窗口宽度( 默认: 910)
类型脚本
组件数据
interface ComponentData {
id: string
type: string
data: Record<string, any>
}
页面数据
interface PageData {
id?: string
components: ComponentData[]
pageSettings?: PageSettings
header_code?: string
body_code?: string
language?: Record<string, any>
}
页面安排
interface PageSettings {
selectedGoogleFont?: string
pageLanguage?: string
pageDirection?: 'ltr' | 'rtl'
additionalHeadCode?: string
additionalBodyCode?: string
customFavicon?: string
customOgImage?: string
customKeywords?: string
customRobotsMeta?: string
customAnalyticsCode?: string
disableGlobalHeadCode?: boolean
disableGlobalBodyCode?: boolean
disableGoogleAnalytics?: boolean
disableFacebookPixel?: boolean
}
全球安排
interface GlobalSettings {
selectedGoogleFont?: string
pageLanguage?: string
pageDirection?: 'ltr' | 'rtl'
globalHeadCode?: string
globalBodyCode?: string
favicon?: string
ogImage?: string
siteKeywords?: string
googleAnalyticsId?: string
facebookPixelId?: string
}
信件类型
type MessageType =
| 'ready'
| 'update'
| 'focus'
| 'highlight'
| 'preview'
| 'meta'
| 'delete'
| 'disableLinks'
| 'newBlock'
编辑器
interface EditorMessage {
type: MessageType
message?: any
data?: any
isMobile?: boolean
}
块选项
interface BlockProps {
isMobile?: boolean
[key: string]: any
}
样式配置
interface StyleConfig {
// Spacing
marginTop?: number
marginBottom?: number
marginTopMobile?: number
marginBottomMobile?: number
padding?: number
paddingMobile?: number
// Width
width?: number
widthMobile?: number
widthPercent?: number
widthPercentMobile?: number
fullWidth?: boolean
fullWidthMobile?: boolean
// Colors
backgroundColor?: string
backgroundColorMobile?: string
textColor?: string
textColorMobile?: string
// Border
borderWidth?: number
borderWidthMobile?: number
borderStyle?: string
borderStyleMobile?: string
borderColor?: string
borderColorMobile?: string
borderRadius?: number
borderRadiusMobile?: number
// Typography
fontFamily?: string
fontFamilyMobile?: string
center?: boolean
centerMobile?: boolean
// Effects
shadowType?: 'none' | 'sm' | 'md' | 'lg' | 'xl' | 'custom'
shadowTypeMobile?: 'none' | 'sm' | 'md' | 'lg' | 'xl' | 'custom'
zIndex?: number
zIndexMobile?: number
// Visibility
showDesktop?: boolean
showMobile?: boolean
// Custom
customId?: string
customCSS?: string
}
信件协议
编辑器 – 预览
update
更新组件数据.
{
type: 'update',
data: ComponentData[],
isMobile: boolean
}
focus
专注具体块.
{
type: 'focus',
message: 'block-id-123'
}
highlight
突出特定块.
{
type: 'highlight',
message: 'block-id-123'
}
preview
切换预览模式 .
{
type: 'preview',
message: true | false
}
disableLinks
禁用链接导航 .
{
type: 'disableLinks',
message: true | false
}
预览 – 编辑器
ready
预览准备好了.
{
type: 'ready',
message: {
registeredTypes: string[]
}
}
focus
用户聚焦一块.
{
type: 'focus',
message: 'block-id-123'
}
highlight
用户突出显示一个块 .
{
type: 'highlight',
message: 'block-id-123'
}
delete
用户想要删除块 .
{
type: 'delete',
message: 'block-id-123'
}
捐款
欢迎捐款! 请读我们的 贡献指南 详细情况.
许可证
麻省理工学院 巴盖尔工作室