因为考虑到后面外部插件市场的扩展,所以需要一个插件管理器来管理外部插件的注册和使用:
class blockManager {private blocks = baseBlocksconstructor() { }getBlocksMap() {return Object.fromEntries(this.blocks.map((block) => [block.type, block]))}getBlocks() {return this.blocks}addBlock(block: any) {this.blocks.push(block)}hasBlock(type: BlockType) {return !!this.getBlocksMap()[type]}}
const blockManagerInstance = new blockManager()这是插件底座,在 BI 平台是物料管理器/套件。
2. 插件注册
注册外部物料, 这里的注册方式比较简单,直接在这里添加,后续可能会提供一个插件市场,第三方可以通过插件市场来注册自己的物料
// 远程物料
blockManagerInstance.addBlock({type: 'button',material: ButtonBlock})blockManagerInstance.addBlock({type: 'form',material: FormBlock})blockManagerInstance.addBlock({type: 'notes',material: NotesBlock})
3. 封装为 Vue 插件
const blocksMap = blockManagerInstance.getBlocksMap()export const blocksMapSymbol = Symbol('blocksMap')export const initBlocks = () => ({install(app: App) {app.provide(blocksMapSymbol, blocksMap)app.config.globalProperties.$blocksMap = blocksMap}})
/*src/main.ts*/import { createApp } from 'vue'import App from './App.vue'const app = createApp(App)app.use(initBlocks())app.mount('#app')
这样把所有物料挂载到应用,方便物料的获取。
4. 物料渲染器
简单的策略模式,通过动态组件渲染
<template><divclass="block-wrapper"ref="blockWrapperRef" @click.stop="selectBlock(block.id)"><component:is="$blocksMap[block.type].material"class="block":blockInfo="block" /></div></template>
<template><smooth-dnd-draggablev-for="(block, i) in blocks":key="block.id"><BlockRenderer:block="block":i="i" /></smooth-dnd-draggable></template>
夜雨聆风