拓冰建站拓冰建站
首页 / 资讯中心 / 正文

GrapesJS Asset Manager 模块 API 详解:从资产集合管理到自定义 UI

GrapesJS Asset Manager 模块 API 详解从资产集合管理到自定义 UI【免费下载链接】grapesjsFree and Open source Web Builder Framework. Next generation tool for building templates without coding项目地址: https://gitcode.com/GitHub_Trending/gr/grapesjsGrapesJS 的 Asset Manager资源管理器负责统一管理编辑器中的所有媒体资源图片、SVG、文档等并为它们提供可视化的选择、上传与展示界面。本文以官方 API 文档为主体结合仓库源码asset_manager 模块深入讲解该模块的配置、事件系统、全部公开方法以及底层实现原理读完你可以熟练地在自己的 GrapesJS 应用中完成资产初始化、程序化增删改查、接入上传服务乃至用自定义 UI 完全替换默认界面。模块初始化与配置对象你可以在编辑器初始化时通过assetManager配置项定制该模块的初始状态传入一个配置对象const editor grapesjs.init({ assetManager: { // options } });编辑器实例化之后即可通过实例获取模块进而调用其 APIconst assetManager editor.AssetManager;核心配置项一览结合 config.ts 中的AssetManagerConfig接口与其默认值模块支持以下关键配置配置项默认值说明assets[]默认资产列表支持字符串 URL 或对象[https://...image1.png, {type: image, src: https://...image2.png, someOtherCustomProp: 1}]noAssets无资产可展示时显示的内容例如No bassets/b here, drag to uploadstylePrefixam-样式前缀upload上传接口地址设为false可禁用上传例如https://endpoint/upload/assetsuploadNamefilesPOST 上传时携带文件的字段名headers{}上传请求的自定义请求头params{}上传请求的自定义参数如 CSRF tokencredentialsinclude上传请求的 credentials 设置可选include、omit等multiUploadtrue是否允许一次请求上传多个文件关闭后文件名不会附加multiUploadSuffixmultiUploadSuffix[]multiUpload开启时追加到uploadName后的后缀autoAddtrue上传成功后自动将响应中的资产加入集合要求服务端返回{ data: [...] }格式的 JSONfetchOptions-定制传给默认 Fetch API 的选项如(options) ({ ...options, method: put })customFetch-用自定义逻辑覆盖 Fetch 上传需返回 Promise如(url, options) axios(url, { data: options.body })uploadFile-完全接管上传流程的自定义函数此时需自行触发全部asset:upload:*事件embedAsBase64true在既无uploadFile也无upload时将资产以 Base64 形式内嵌handleAdd-处理内置「添加图片」表单提交如(textFromInput) editor.AssetManager.add(textFromInput)beforeUpload-上传前回调返回false可取消上传showUrlInputtrue是否显示资产 URL 输入框customfalse避免渲染默认资产管理器可传布尔值或{ open, close }对象dropzone/openAssetsOnDrop/dropzoneContentfalse/true/全编辑器拖放上传相关配置在源码中已标记为deprecated从源码可以看出模块在构造时会先执行defConfig()得到上述默认配置并将pStylePrefix拼接到stylePrefix前index.ts。初始化完成后onLoad()会用this.config.assets重置全局集合index.ts即配置中的assets数组会成为资产的初始来源。事件系统Available EventsAsset Manager 通过editor.on(...)暴露一套完整的事件。事件定义集中在 types.ts 的AssetsEvents枚举中事件触发时源码会通过__propEv同时通知编辑器与全局集合index.ts。全部事件如下集合增删改事件asset:add—— 新资产加入集合回调参数为该资产对象editor.on(asset:add, (asset) { ... });asset:remove—— 资产从集合中移除回调参数为该资产editor.on(asset:remove, (asset) { ... });源码还额外定义了asset:remove:before在移除前触发见 types.tsasset:update—— 资产被更新回调参数为资产对象和变更内容对象editor.on(asset:update, (asset, updatedProps) { ... });打开与关闭事件asset:open—— 资产管理器被打开editor.on(asset:open, () { ... });asset:close—— 资产管理器被关闭editor.on(asset:close, () { ... });源码中这两个事件由open-assets命令的运行/停止回调触发index.ts因此asset:open/asset:close实际与命令open-assets的生命周期绑定。上传事件asset:upload:start—— 上传开始editor.on(asset:upload:start, () { ... });asset:upload:end—— 上传结束无论成功与否editor.on(asset:upload:end, (result) { ... });asset:upload:error—— 上传出错editor.on(asset:upload:error, (error) { ... });asset:upload:response—— 收到上传响应editor.on(asset:upload:response, (res) { ... });自定义 UI 事件asset:custom—— 供自定义 Asset Manager UI 使用详见下文「自定义 UI」一节editor.on(asset:custom, ({ container, assets, ... }) { ... });兜底事件asset—— 以上所有事件的统称回调参数为包含本次事件全部可用数据的对象editor.on(asset, ({ event, model, ... }) { ... });配合 TypeScript 使用时可参考AssetsEventCallback接口获取每个事件的精确回调签名types.ts。公开方法详解模块公开了 9 个方法其实现全部位于 index.ts 中。下面逐个说明。open —— 打开资产管理器打开资产管理器支持传入选项对象assetManager.open({ select(asset, complete) { const selected editor.getSelected(); if (selected selected.is(image)) { selected.addAttributes({ src: asset.getSrc() }); // 默认 AssetManager UI 会在单击资产时触发 select(asset, false) // 在双击资产时触发 select(asset, true) complete assetManager.close(); } } }); // 指定自定义类型前提是已声明了对应类型的资产 assetManager.open({ types: [doc], ... });参数说明optionsObject可选默认{}options.typesArrayString默认[image]要展示的资产类型options.selectFunction可选资产被选中时执行的操作若不指定则什么都不会发生。从源码看open()实际上是运行了内部命令open-assetsconst assetCmd open-assets并把types: [image]与一个空的select作为默认值合入选项后交给cmd.runindex.ts。这意味着你也可以直接用editor.runCommand(open-assets, {...})达到相同效果。close —— 关闭资产管理器assetManager.close();源码实现为cmd.stop(assetCmd)即停止open-assets命令index.ts随后会触发asset:close事件。isOpen —— 检测是否处于打开状态assetManager.isOpen(); // true | false返回Boolean。实现上通过cmd.isActive(assetCmd)判断open-assets命令是否处于激活状态index.ts。add —— 添加新资产向集合中添加一个或多个资产URL 假定唯一// 以字符串形式 assetManager.add(http://img.jpg); assetManager.add([http://img.jpg, ./path/to/img.png]); // 使用对象可指定类型及更多元信息 assetManager.add({ // type: image, // image 为默认类型 src: http://img.jpg, height: 300, width: 200, }); assetManager.add([{ src: img2.jpg }, { src: img2.png }]);参数说明assetString | Object | ArrayString | ArrayObjectURL 字符串或表示资源的对象optsObject可选默认{}。返回新增的Asset。源码中若未显式指定opts.at会默认置为0即新资产插入到集合头部index.ts。传入字符串时Assets.ts 中注册的image类型isType函数会把字符串统一转换为{ type: image, src: value }对象。get —— 按 URL 查询资产const asset assetManager.get(http://img.jpg);参数srcString—— 资产的 URL。返回Asset | null。实现为this.all.where({ src })[0] || nullindex.ts。之所以能按src精确匹配是因为 Asset 模型的idAttribute被设置为src见 Asset.ts这正是文档强调「URLs are supposed to be unique」的根本原因。getAll —— 获取全局集合返回包含全部资产的全局集合assetManager.getAll(); // CollectionAsset返回CollectionAsset。getAllVisible —— 获取可见集合返回可见集合即当前实际被渲染出来的资产assetManager.getAllVisible(); // CollectionAsset返回CollectionAsset。「全局集合」与「可见集合」是理解该模块的关键模块构造时创建了独立的assetsVis集合并建立同步关系——全局集合新增资产时同步加入可见集合移除时同步移出index.ts。render()方法会执行this.assetsVis.reset(toRender)来重置可见集合index.ts从而决定渲染哪些资产。remove —— 移除资产const removed assetManager.remove(http://img.jpg); // 或传入 Asset 对象 const asset assetManager.get(http://img.jpg); assetManager.remove(asset);参数assetString | Asset—— 资产或其 URLoptsRemoveOptions可选。返回被移除的Asset。方法内部委托给基类Module的__remove完成index.ts。getContainer —— 获取容器元素返回 Asset Manager 的容器assetManager.getContainer(); // HTMLElement返回HTMLElement。实现优先返回行为配置中的container否则返回默认视图的根元素this.am?.elindex.ts。你可以在拿到容器后直接向其中插入自定义 DOM。Asset 模型 API文档中出现的[Asset]即资产模型实例其定义与全部方法见 Asset.ts对应 API 文档 asset.md。核心属性typeString—— 资产类型如imagesrcString—— 资产 URL如https://.../image.png。默认的image类型在此基础上扩展了unitDimpx、height、width属性见 AssetImage.ts。实例方法getType()—— 获取资产类型// Asset: { src: https://.../image.png, type: image } asset.getType(); // - image返回String实现为this.get(type)。getSrc()—— 获取资产 URL// Asset: { src: https://.../image.png } asset.getSrc(); // - https://.../image.png返回String实现为this.get(src) || 。getFilename()—— 基于src获取文件名// Asset: { src: https://.../image.png } asset.getFilename(); // - image.png // Asset: { src: https://.../image } asset.getFilename(); // - image返回String。源码实现为this.getSrc().split(/).pop().split(?).shift()即截取最后一个/之后、去掉查询字符串的部分Asset.ts。getExtension()—— 基于src获取扩展名// Asset: { src: https://.../image.png } asset.getExtension(); // - png // Asset: { src: https://.../image } asset.getExtension(); // - 返回String实现为this.getFilename().split(.).pop()Asset.ts。注意无扩展名时返回空字符串而非undefined。上传流程的源码级拆解模块的默认 UI 内置了拖放上传器FileUploader.ts。完整上传链路如下选择文件点击上传区选择文件或直接拖拽change [data-input]事件触发uploadFile文件过滤根据accept属性校验文件类型源码注释 #6032 说明浏览器在拖拽场景不会强制校验accept因此实现了isFileAccepted辅助函数进行过滤被全部拒绝时不执行任何操作前置钩子调用beforeUpload(files)返回false则取消上传构造请求体将params中的自定义参数追加到FormData若multiUpload为true每个文件以uploadName multiUploadSuffix默认files[]为字段名追加否则只追加第一个文件发起请求自动补充X-Requested-With: XMLHttpRequest请求头若未自定义使用fetchmethod: post、credentials按配置或customFetch若配置了fetchOptions则先对其结果做转换响应处理onUploadResponse解析 JSON触发asset:upload:response若autoAdd为true则把json.data中的资产以{ at: 0 }插入全局集合最后触发asset:upload:end错误处理请求失败时onUploadError打印错误、触发asset:upload:error并同样以onUploadEnd收尾。Base64 内嵌模式当既未配置upload也未配置uploadFile且embedAsBase64为true时模块使用FileReader将文件读取为 Data URLembedAsBase64静态方法对图片类型还会额外加载Image对象以探测宽高一并写入资产数据FileUploader.ts。这种模式下asset:upload:start不会触发因为根本没有网络请求。服务端响应须符合如下 JSON 结构autoAdd: true时才会被自动入库{ data: [ https://.../image.png, // ... { src: https://.../image2.png, type: image, height: 100, width: 200, }, // ... ]; }实战组合打开管理器并应用到选中组件将open、getSrc、close组合起来即可实现「打开资产管理器 → 选择图片 → 应用到画布中选中的图片组件」的完整闭环const assetManager editor.AssetManager; assetManager.open({ types: [image], // 默认值 select(asset, complete) { const selected editor.getSelected(); if (selected selected.is(image)) { selected.addAttributes({ src: asset.getSrc() }); // 单击触发 select(asset, false)双击触发 select(asset, true) complete assetManager.close(); } }, });若不加select回调资产选择时不会有任何动作对应源码open()中默认的select: () {}。此外使用全局/可见双集合机制还可以实现「分类筛选」这类高级交互先向全局集合add带category属性的资产再用render()传入过滤后的资产数组控制可见集合完整示例见 Assets 模块指南。自定义 UI 与类型扩展使用asset:custom替换默认界面默认 UI 仅适合简单场景若要加入搜索框、过滤器等复杂功能可设置custom: true并订阅asset:custom事件const editor grapesjs.init({ // ... assetManager: { // ... custom: true, }, }); editor.on(asset:custom, (props) { // props.open (boolean) - 资产管理器是否处于打开状态 // props.assets (ArrayAsset) - 全部资产 // props.types (ArrayString) - 请求的资产类型如 [image] // props.close (Function) - 关闭资产管理器的回调 // props.remove (FunctionAsset) - 移除资产的回调 // props.select (FunctionAsset, boolean) - 选择资产的回调 // props.container (HTMLElement) - 应挂载 UI 的容器元素 // 在这里编写渲染/更新 UI 的逻辑 });从源码看asset:custom由__trgCustom触发其数据由__customData()组装除上述字段外还包含am模块实例与options本次打开时的选项并且仅在存在container或配置了custom.open时才会触发index.ts。若你的 UI 是完全独立的外部模块例如自己的弹窗可改用对象形式的配置并务必实现close否则编辑器无法通过am.close()关闭const editor grapesjs.init({ // ... assetManager: { // ... custom: { open(props) { // props 与 asset:custom 事件中的一致 // 初始化并打开外部资产管理器 // 外部库关闭时须调用 props.close() 同步状态 // 例如myAssetManager.on(close, () props.close()) }, close(props) { // 关闭外部资产管理器 }, }, }, });注册自定义资产类型模块核心只实现了image一种类型见 Assets.ts 的types注册表但通过addType(id, definition)可以轻松扩展。定义由model业务逻辑、view展示逻辑与isType类型识别函数三部分组成assetManager.addType(my-type, { model: {}, view: {}, isType: (value) {}, });视图层基于 AssetView.ts 的template()/getPreview()/getInfo()/updateTarget()钩子实现AssetImageView.ts 即是最好的参考实现。更完整的自定义类型开发流程含 SVG 资产案例与类型继承请参阅 Assets 模块指南。小结Asset Manager 是一个「轻核心、可扩展」的模块核心仅内置image类型但通过add/get/getAll/getAllVisible/remove等 API 支撑起全局集合与可见集合的双层管理通过open/close/isOpen与open-assets命令联动控制界面显隐通过asset:*事件族覆盖增删改、开关与上传全链路最后以asset:customcustom配置为完全自定义 UI 留下入口。理解了集合、命令与事件这三条主线你就能在项目中灵活驾驭它。【免费下载链接】grapesjsFree and Open source Web Builder Framework. Next generation tool for building templates without coding项目地址: https://gitcode.com/GitHub_Trending/gr/grapesjs创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门