Amis源码 embed渲染方法解析(json结构渲染原理):

js sdk中的渲染函数embed使用方式如下:

const amis = amisRequire("amis/embed");  

const amisScoped = amis.embed( self.$refs["mnode"],amisJSON, {}, amisEnv); //env会有默认值,默认值与传来的参数进行合并({默认值, ...env})

amisScoped.getComponentByName("crud");

embed函数源码在examples/embed.tsx中

import {  render as renderAmis } from 'amis ';

1.核心是通过 {renderAmis(schema, amisProps, amisEnv)}渲染的. (amisEnv里是fetcher,isCancel,tracker等)

2.返回一个scoped对象,里面属性(getComponentByName等)是在amis-core/src/Scoped.tsx中调用scopeRef方法赋值的

render函数在amis-core/src/index.tsx中:

没什么东西,只是return 了一个AMISRenderer,我们直接看AMISRenderer:

1.首先会从stores缓存中获取store(RendererStore树),按amisEnv.session指定的值来获取,amisEnv.session不存在则用固定值'global'

2.若缓存store(RendererStore树)不存在,则会创建一个RendererStore类型的mobx树,将env设置为树的环境配置。然后会将此store(树)缓存到stores对象中(key为amisEnv.session || 'global')。

3.若缓存store(RendererStore树)存在,获取缓存store中的env,并做assign更新env。

默认 env 会被缓存,所以新传入的 env 不会替换旧的除非先删了旧的,新的才会生效

另外:RendererStore是一个渲染器store也是rootStore. RendererStore里还有个单例stores是用来维护amisJSON渲染时生成的一个个组件store树(page、form、crud等),组件销毁时从stores中移除。

4.最终走<ScopedRootRenderer> 并传递props进行后续处理

ScopedRootRenderer在amis-core/src/Root.tsx中导出:

1.default导出函数及解释:

export default StatusScoped(Scoped(Root));

Scoped函数:传入Root 作为ComposedComponent参数, 返回ScopedComponent

StatusScoped函数:传入 Scoped(Root) 作为ComposedComponent, 返回一个自定义class

2.自定义class 在amis-core/src/StatusScoped.tsx中:

主要是 向下传递了一个statusStore( StatusStore.create({}) )给dialog drawer等模态框级别使用,独立占用一个状态管理作用域

3.ScopedComponent在amis-core/src/Scoped.tsx中:

主要封装了一个scoped对象(包含getComponentByName等属性方法)并作为provide向下传递。 此外还调用了scopeRef方法(examples/embed.tsx中传递过来的)

4.在amis-core/src/Root.tsx中:

进行reduce处理,rootWrappers数组中有wrapper函数则进行合并处理,空数组直接返回初始值进行<RootRenderer schema = {{type: 'page'}}>

最终走<RootRenderer> 并传递props进行后续处理

Root.tsx中renderChild方法:

export function renderChild(prefix: string,node: SchemaNode,props: renderChildProps
): ReactElement {if (Array.isArray(node)) {return renderChildren(prefix, node, props);}//...省略return (<SchemaRendererrender={renderChild as any}{...props}schema={schema}propKey={schema.key}$path={`${prefix ? `${prefix}/` : ''}${(schema && schema.type) || ''}`}/>);
}

RootRenderer在amis-core/src/RootRenderer.tsx中

创建顶级store(RootStore树),并添加到rootStore.stores中(rootStore即RendererStore),这个store会作为topStore向下传递。  props.rootStore.addStore({storeType: RootStore.name})

使用amisProps.data初始化顶级store数据域 。  this.store.initData(props.data);

最终调用this.props.render函数(这个props.render是Root.tsx中renderChild方法,底层走<SchemaRenderer>完成渲染)进行render渲染page

SchemaRenderer在amis-core/src/SchemaRenderer.tsx中

  核心是利用renderer Component进行渲染(amis/src/renderers中定义的),根据schema的type,找到@renderer(type: 'xxx’)注册的渲染器,将schema数据作为props传入渲染不同Component。

  由对应的renderer Component内部控制body子节点渲染:比如Page会判断schema的body存在则调用this.props.render('body', body)渲染body子节点(这个props.render是SchemaRenderer.tsx中的 renderChild方法进行了一些预处理,最终还是调用的Root.tsx中renderChild走<SchemaRenderer>完成渲染】)

    const Component = renderer.component;let props = {$schema: schema,ref: this.refFn,
//传递的是SchemaRenderer.tsx中的 renderChild方法(进行了一些预处理,然后还是调用的Root.tsx中renderChild渲染<SchemaRenderer>)render: this.renderChild, rootStore,statusStore,dispatchEvent: this.dispatchEvent,mobileUI: schema.useMobileUI === false ? false : rest.mobileUI};//...省略// 自动解析变量模式,主要是方便直接引入第三方组件库,无需为了支持变量封装一层if (renderer.autoVar) {for (const key of Object.keys(schema)) {if (typeof props[key] === 'string' && isExpression(props[key])) {props[key] = resolveVariableAndFilter(props[key],props.data,'| raw');}}}const component = isClassComponent ? (<Component {...props} ref={this.childRef} />) : (<Component {...props} />);return this.props.env.enableAMISDebug ? (<DebugWrapper renderer={renderer}>{component}</DebugWrapper>) : (component);}
}

SchemaRenderer.tsx中renderChild:

  renderChild(region: string,node?: SchemaNode,subProps: {data?: object;[propName: string]: any;} = {}) {//这个render是Root.tsx中的renderChild方法(底层<SchemaRenderer>渲染)let {schema: _, $path: __, env, render, ...rest} = this.props;let {path: $path} = this.resolveRenderer(this.props);const omitList = RENDERER_TRANSMISSION_OMIT_PROPS.concat();if (this.renderer) {const Component = this.renderer.component;Component.propsList &&omitList.push.apply(omitList, Component.propsList as Array<string>);}return render!(`${$path}${region ? `/${region}` : ''}`, node || '', {...omit(rest, omitList),defaultStatic:(this.renderer?.type &&['drawer', 'dialog'].includes(this.renderer.type)? false: undefined) ??this.isStatic ??(_.staticOn? evalExpression(_.staticOn, rest.data): _.static ?? rest.defaultStatic),...subProps,data: subProps.data || rest.data, //首先取传来的data 没有 则用this.props.data父组件dataenv: env});}

amis 的渲染过程是将 json 转成对应的 React 组件。先通过 json 的 type 找到对应的 Component,然后把其他属性作为 props 传递过去完成渲染。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/19626.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TiDB-从0到1-部署篇

TiDB从0到1系列 TiDB-从0到1-体系结构TiDB-从0到1-分布式存储TiDB-从0到1-分布式事务TiDB-从0到1-MVCCTiDB-从0到1-部署篇 一、TiUP TiUP是TiDB4.0版本引入的集群运维工具&#xff0c;通过TiUP可以进行TiDB的日常运维工作&#xff0c;包括部署、启动、关闭、销毁、弹性扩缩容…

23种软件设计模式——工厂模式

工厂模式 工厂模式&#xff08;Factory Pattern&#xff09;是 Java 中最常用的设计模式之一&#xff0c;它提供了一种创建对象的方式&#xff0c;使得创建对象的过程与使用对象的过程分离。 工厂模式提供了一种创建对象的方式&#xff0c;而无需指定要创建的具体类。 通过使…

身份认证与口令攻击

身份认证与口令攻击 身份认证身份认证的五种方式口令认证静态口令动态口令(一次性口令)动态口令分类 密码学认证一次性口令认证S/KEY协议改进的S/KEY协议 其于共享密钥的认证 口令行为规律和口令猜测口令规律口令猜测 口令破解操作系统口令破解Windows密码存储机制Windows密码破…

2024新版二开微信发卡小程序源码卡密系统流支持量主

2024新版二开微信发卡小程序源码卡密系统流支持量主。裂变扩展多种领取模式二次开发的发卡小程序源码&#xff0c;其后台采用PHP编写&#xff0c;支持用户通过付费购卡或者观看视频广告领取卡密&#xff0c;该小程序还支持流量主&#xff0c;因为功能需要&#xff0c;我就进行了…

WinSW使用说明

WinSW使用说明 Windows系统下部署多个java程序 场景&#xff1a; 多个java的jar程序&#xff0c;通常来说一个程序使用一个cmd窗口&#xff0c;通过java -jar xxx.jar 命令来运行。这样如果程序多了打开cmd窗口也就多了。 解决&#xff1a; 通过使用WinSW程序&#xff0c;把ja…

VisualSVN Server/TortoiseSVN更改端口号

文章目录 概述VisualSVN Server端更改端口号TortoiseSVN客户端更改远程仓库地址 概述 Subversion&#xff08;SVN&#xff09;是常用的版本管理系统之一。部署在服务器上的SVN Server端通常会在端口号80&#xff0c;或者端口号443上提供服务。其中80是HTTP访问方式的默认端口。…

AndroidFlutter混合开发

为什么要有混合开发 我们知道&#xff0c;Flutter是可以做跨平台开发的&#xff0c;即一份Flutter的Dart代码&#xff0c;可以编译到多个平台上运行。这么做的好处就是&#xff0c;在不降低多少性能的情况下&#xff0c;尽最大可能的节省开发的时间成本&#xff0c;直接将开发…

带文字的短视频:成都鼎茂宏升文化传媒公司

带文字的短视频&#xff1a;视觉与文字的交织艺术 在信息爆炸的时代&#xff0c;短视频以其直观、生动的视觉呈现方式&#xff0c;迅速成为人们获取信息、娱乐休闲的重要渠道。然而&#xff0c;随着人们对内容深度和质量要求的提升&#xff0c;成都鼎茂宏升文化传媒公司单纯的…

项目4 移动电商运维自动化

项目引入 在一次移动电商系统发布更新上&#xff0c;由于我的不小心&#xff0c;错误地删除了生产服务器上的执行代码&#xff0c;导致整个移动电商系统页面都无法访问&#xff0c;最后花很长时间才恢复&#xff0c;这次事故给公司带来了不小的麻烦。 Philip组织整个运维团队进…

多屏多机同控!天途首发瑶光智控地面站

瑶光智控地面站全新发布&#xff01;高性能处理器&#xff0c;高亮三屏显示。内置天途云控系统&#xff0c;融合图传、控制、存储和数据处理等功能与一体&#xff0c;强大算力&#xff0c;高度集成无人机、无人船、无人车和机械狗等多种无人装备进行云控云算。 内置4G公网通讯模…

LabVIEW调用外部DLL(动态链接库)

LabVIEW调用外部DLL&#xff08;动态链接库&#xff09; LabVIEW调用外部DLL&#xff08;动态链接库&#xff09;可以扩展其功能&#xff0c;使用外部库实现复杂计算、硬件控制等任务。通过调用节点&#xff08;Call Library Function Node&#xff09;配置DLL路径、函数名称和…

Django ORM入门指南:从概念到实践,掌握模型创建、迁移与视图操作

系列文章目录 Django入门全攻略&#xff1a;从零搭建你的第一个Web项目Django ORM入门指南&#xff1a;从概念到实践&#xff0c;掌握模型创建、迁移与视图操作[Django ORM实战&#xff1a;模型字段与元选项配置&#xff0c;以及链式过滤与QF查询详解]还在写0.0… 文章目录 系…

道歉性质的《情况说明》应如何写,才能赢得对方的谅解?

道歉性质的《情况说明》应如何写&#xff0c;才能赢得对方的谅解&#xff1f; ——从“成都地铁被诬陷偷拍案”两涉事女的《情况说明》中想到了什么&#xff1f; 据九派新闻报道&#xff0c;在“成都地铁被诬陷偷拍案”中&#xff0c;近日两名当事女子罗某某和曾某某首次公开回…

网关(GateWay)- 快速使用

引入依赖 <!-- gateway --> <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId> </dependency> 路由配置 server:port: 8088 spring:application:name: api-gatew…

零基础学会asp.net做网站/公众号/小程序之三:实战初体验(简单程序教学)

关注我&#xff0c;持续分享逻辑思维&管理思维&面试题&#xff1b; 可提供大厂面试辅导、及定制化求职/在职/管理/架构辅导&#xff1b; 博主在互联网大厂深耕近二十年&#xff0c;从一线码农做起&#xff0c;到人工智能公司副总裁。希望把过往经验总结出来&#xff0…

MySQL 命令总结篇-思维导图

一些常用命令以思维导图形式总结在这里了&#xff0c;掌握这些进行MySQL基本操作绝对没问题&#xff0c;加油&#xff01;友友们可以根据这些思维导图进行知识总结。 目录 一、快速上手 二、SQL 语句分类&#xff08;DDL、DML、DQL、DCL&#xff09; 三、数据类型 四、约束…

探索AI去衣技术中的反射应用

在当今数字时代&#xff0c;人工智能&#xff08;AI&#xff09;技术的飞速发展已经渗透到了我们生活的方方面面。其中&#xff0c;图像处理和计算机视觉作为AI的重要分支&#xff0c;正不断推动着创新应用的边界。今天&#xff0c;我们要探讨的是一个颇具争议但又技术上颇为有…

[Algorithm][动态规划][子序列问题][最长递增子序列][摆动序列]详细讲解

目录 0.子序列 vs 子数组1.最长递增子序列1.题目链接2.算法原理详解3.代码实现 2.摆动序列1.题目链接2.题目链接3.代码实现 0.子序列 vs 子数组 子序列&#xff1a; 相对顺序是跟源字符串/数组是一致的但是元素和元素之间&#xff0c;在源字符串/数组中可以是不连续的一般时间…

金融行业数字化上云及信创改造过程中的一些问题及解决方案|合集①

Q&#xff1a;对金融机构来讲&#xff0c;什么是一切业务运行的前提&#xff1f; 金融机构的业务连续性对系统的稳定性要求极高。任何系统故障都可能导致严重的业务中断和经济损失。因此&#xff0c;金融机构需要IT基础架构能够提供高稳定性的服务&#xff0c;确保业务的连续运…

Android Display Graphics #1 整体框架介绍一

软件基础 Android的framework层提供了一系列的图像渲染API&#xff0c;可绘制2D和3D。简单理解就是上层开发APP的小伙伴提供了接口&#xff0c;开发者可以直接显示对应的自己内容。但如果掌握了Display底层逻辑再写上层app&#xff0c;会有掌控力&#xff0c;出问题可以根据lo…