当前位置: 首页 > news >正文

建立无需build的react单页面应用SPA框架(2)

react-18.1.0,rc-easyui-1.2.9,babel-7.17.11

SPA还要处理的问题:

(一)tabs切换事件通知

tabs切换时,自己的框架需要处理组件的生命周期,要有active/deactive,让组件能知道何时创建或清除一些资源的使用,比如setInterval/clearInterval。

赋予active/deactive事件通知,在tabs元件的onTabSelect/onTabUnselect事件处理就行了。如何通知?分两种情况:

(1)类式组件,让它定义一个function foil_onStateChanged(state)函数来接收。

page.likeButton.jsxclass Com_LikeButton extends React.Component {constructor(props) {console.log('likebutton constructor');super(props);this.state = { liked: false };}foil_onStateChanged(state){console.log('likebutton foil_onStateChanged',state);}render() {console.log('likeButton render',this.props);if (this.state.liked) {console.log(acroML.browserEngine.LCID);return t('&File');}return (<button onClick={() => this.setState({ liked: true })}>{t('&Edit')}</button>);}
}
export default Com_LikeButton;

(2)函数式组件,通过props参数传递。

page.timer.jsxexport default function COM_timer(props){console.log('page timer function:',props.foil.state);let [time,setTime]=React.useState(0);function getNow(){return time;}//timerID不参与渲染,用useReflet timerID=React.useRef(null);console.log('timerID:',timerID.current);if (props.foil.state=='create' || props.foil.state=='active'){if (timerID.current==null){console.log('start timer')timerID.current=setInterval(function(){console.log('timer:',time);time++;setTime(time);},1000);}}else if (props.foil.state=='deactive'||props.foil.state=='destroy'){if (timerID.current!=null){console.log('clear timerID:',timerID.current);clearInterval(timerID.current);timerID.current=null;}}return(<div><span>{t('&File')}</span><span>{getNow()}</span></div>)
}

虽然类组件有componentDidMount/componentWillUnmount两个事件来判断组件创建和销毁,但是函数式组件没有。如果框架要统一事件,最好把create/destroy事件也加进去。create可以在异步组件的componentDidMount处理,destroy就不能在动态元件的componentWillUnmount处理了,甚至不能在tabs的onTabClose事件处理,来不及了,虽然类组件可以,但函数式组件不会触发渲染重调用。

com.bizCom.jsximport { Suspense,Component } from 'react';
class Com_bizCom extends React.Component {constructor(props) {console.log('Com_bizCom constructor');super(props);props.foil.onStateChanged=this.foil_onStateChanged.bind(this);this.state={foil:{state:'create'}}}shouldComponentUpdate(nextProps, nextState) {//console.log(nextProps);//文件相同时不要再渲染,LCID改变后必须重渲染//if (nextProps.file && (nextProps.file === this.props.file)) return false;return true;}foil_onStateChanged(state){console.log('bizCom foil_onStateChanged',state);console.log(this.com);if (this.com.ref){//React.Component类组件可以通过函数通知状态if (this.com.ref.current.foil_onStateChanged){this.com.ref.current.foil_onStateChanged(state);}}else{//函数式组件只能通过proprs传递状态,然后bizCOM重渲染if (this.state.foil.state!=state){this.state.foil.state=state;this.com.props.foil.state=state;this.setState(this.state);}}}componentDidMount(){if (this.com.ref){//只需要组件元件通知一下create状态,函数元件第一渲染已经把create带到props.foil.statethis.com.ref.current.foil_onStateChanged('create');}}componentWillUnmount(){let self=this;console.log('bizCom componentWillUnmount',this.com.ref);//不在这里处理子函数式组件的销毁通知,来不及了,子函数式组件不会调用渲染//在easyui tab关闭前处理}render() {let self=this;console.log('Com_bizCom render',this.props);let file=this.props.file;if (!file) return null;/*let Com=React.lazy(function(){import函数不能加载jsxreturn import(file);});return(<Suspense><Com></Com></Suspense>)*/let obj=window.require(file);//console.log(obj);if (obj.__esModule===true) obj= obj.default;// console.log(typeof obj);// console.log(obj.prototype);console.log(self.com);let ops=null;if (self.com){ops=self.com.props;}else{ops={foil:{state:'create'}};if (obj.prototype && obj.prototype.isReactComponent){//类组件才有ref,函数式组件不能有refops.ref=React.createRef();}}let com=React.createElement(obj,ops);self.com=com;return com;}
}
export default Com_bizCom;

要在tabs的panel关闭前处理,查找easyui tabs源码,找到handleTabClose函数,hook一下:

com.right.jsx
............componentDidMount(){let self=this;console.log('right componentDidMount');console.log(this.ref_tabs.current.handleTabClose);//hook handleTabClose这个函数,在关闭panel前通知到bizCom里面的原件要销毁了做一些清理工作,比如清除timerlet fn=this.ref_tabs.current.handleTabClose;this.ref_tabs.current.handleTabClose=function(panel){console.log('handleTabClose',panel);let bizCom=self.getBizCom(panel);bizCom.props.foil.onStateChanged('destroy');//必须用异步,否则子函数式组件不会被调用刷新setTimeout(function(){fn.call(self.ref_tabs.current,panel);}, 0);}}

(二)主界面切换显示的语言

只要在根原件把LCID设置为响应式,改变时,tabs各个组件会刷新。

com.root.jsximport Com_Main from './com.main.jsx';
// import Com_acroMLStub from './com.acroML.stub.jsx';
export default function COM_Root(){console.log('root',acroML.browserEngine.LCID);let [LCID,setLCID]=React.useState(acroML.browserEngine.LCID);acroML.browserEngine.switchLanguage=function(){//console.log(acroML.browserEngine.LCID);setLCID(acroML.browserEngine.LCID);//console.log(LCID);}//<Com_acroMLStub>return(<Com_Main></Com_Main>);
}

相关文章:

建立无需build的react单页面应用SPA框架(2)

react-18.1.0&#xff0c;rc-easyui-1.2.9&#xff0c;babel-7.17.11 SPA还要处理的问题&#xff1a; &#xff08;一&#xff09;tabs切换事件通知 tabs切换时&#xff0c;自己的框架需要处理组件的生命周期&#xff0c;要有active/deactive&#xff0c;让组件能知道何时创…...

C# char曲线控件

一、char曲线显示随机数数据 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading; using Syst…...

远程访问本地jupyter notebook服务 - 无公网IP端口映射

文章目录 前言1. Python环境安装2. Jupyter 安装3. 启动Jupyter Notebook4. 远程访问4.1 安装配置cpolar内网穿透4.2 创建隧道映射本地端口 5. 固定公网地址 前言 Jupyter Notebook&#xff0c;它是一个交互式的数据科学和计算环境&#xff0c;支持多种编程语言&#xff0c;如…...

flume系列之:记录一次消费大量Debezium数据,数据包含dml语句比较大,造成数据堆积在channel的解决方法

flume系列之:记录一次消费大量Debezium数据,数据包含dml语句比较大,造成数据堆积在channel的解决方法 一、背景二、相关技术博客三、flume层面解决方法四、debezium数据采集层面解决方法一、背景 Debezium采集了大量的数据,数据包含DMl语句,数据本身比较大。flume消费了大…...

Could not find artifact com.pageOffice:pageOffice:pom:4.3.0.2 in aliyunmaven

Could not find artifact com.pageOffice:pageOffice:pom:4.3.0.2 in aliyunmaven (https://maven.aliyun.com/repository/public) 仓库服务 阿里云云效 Maven 是什么 阿里云Maven中央仓库为 阿里云云效 提供的公共代理仓库&#xff0c;帮助研发人员提高研发生产效率&#x…...

2023年9月数据治理/项目管理/产品管理/商务礼仪企业内训定制

在节奏飞驰、风起云涌的企业世界中&#xff0c;为了企业的蓬勃发展&#xff0c;可以在内部或者外部挑选有经验的老师进行培训和学习。简而言之&#xff0c;任何一个企业想要发展&#xff0c;都少不了进行内训。 企业内训的好处 提高员工的技能和知识水平 通过不断地学习和培训…...

后端面试话术集锦第 九 篇:Activiti工作流面试话术

这是后端面试集锦第九篇博文——Activiti工作流面试话术❗❗❗ 1. 工作流话术 工作流这块儿,实际在工作中使用的时候,Activiti用的居多,当然还有一些其他的工作流引擎。 在网上看了也大概看了一下,其他的像JBPM以及workflow等用的情况来讲不是很多。 所以说Activiti目前…...

JS中方法、函数、属性是一个东西吗

在 JavaScript 中&#xff0c;方法、函数和属性是相关但不完全相同的概念。 方法&#xff08;Method&#xff09;&#xff1a;在对象中&#xff0c;方法是对象的属性&#xff0c;但它的值是一个函数。方法可以通过对象来调用&#xff0c;并且可以访问对象的属性和其他方法。 …...

面经:微服务

文章目录 参考资料一. 微服务概述1. CAP理论2. BASE理论3. SpringBoot 与 SpringCloud对比 二. 服务注册&#xff1a;Zookeeper,Eureka,Nacos,Consul1. Nacos两种健康检查方式&#xff1f;2. nacos中负责负载均衡底层是如何实现的3. Nacos原理4. 临时实例和持久化(非临时)实例 …...

K8s 持久化存储有几种方式?一文了解本地盘/CSI 外接存储/K8s 原生存储的优缺点

当今云原生环境中&#xff0c;Kubernetes&#xff08;K8s&#xff09;已成为既定的容器编排工具。随着 K8s 的普及&#xff0c;存储也成为 K8s 用户关注的一个重要问题&#xff1a;为了满足不同的场景需求&#xff0c;K8s 可以支持基于不同架构的多种存储方案。这些方案间有什么…...

【MySQL】3、MySQL的索引、事务、存储引擎

create table class (id int not null,name char(10),score decimal(5,2)); insert into class values (1,zhangsan,80.5); update class set namewangwu,passwd123 where id2; select * from class where id2; drop 索引的概念 是一种帮助系统&#xff0c;能够更快速的查询信…...

【Hello Algorithm】链表相关算法题

本篇博客介绍&#xff1a; 介绍下链表相关的算法题 链表相关算法题 快慢指针回文结构链表将单向链表按某值划分为左边小&#xff0c;中间相等&#xff0c;右边大的形式复制带随机指针的链表 链表相关的算法题其实都算不上难 我们真正要考虑的是一些边界问题 事实上链表题就是在…...

自动化管理管理工具----Ansible

目录 ​编辑 一、Ansible概念 1.1特点 二、工作机制&#xff08;日常模块&#xff09; 2.1 核心程序 三、Ansible 环境安装部署 四、ansible 命令行模块 4.1command 模块 4.2shell 模块 4.3cron 模块 4.4user 模块 4.5group 模块 4.6copy模块 4.7file模块 4.8ho…...

深入理解css3背景图边框

border-image知识点 重点理解 border-image-slice 设置的值将边框背景图分为9份&#xff0c;图像中间的舍弃&#xff0c;其他部分图像对应边框的相应区域放置&#xff0c;上右下左四角固定&#xff0c;border-image-repeat设置的是除四角外其他部分的显示方式。 截图来自菜鸟教…...

【rust/egui】(六)看看template的app.rs:TextEdit

说在前面 rust新手&#xff0c;egui没啥找到啥教程&#xff0c;这里自己记录下学习过程环境&#xff1a;windows11 22H2rust版本&#xff1a;rustc 1.71.1egui版本&#xff1a;0.22.0eframe版本&#xff1a;0.22.0上一篇&#xff1a;这里 TextEdit 文本编辑框 其定义为&#…...

Redis内存空间预估与内存优化策略:保障数据安全与性能的架构实践

推荐阅读 AI文本 OCR识别最佳实践 AI Gamma一键生成PPT工具直达链接 玩转cloud Studio 在线编码神器 玩转 GPU AI绘画、AI讲话、翻译,GPU点亮AI想象空间 资源分享 史上最全文档AI绘画stablediffusion资料分享 AI绘画关于SD,MJ,GPT,SDXL百科全书 「java、python面试题」…...

【zookeeper】zookeeper集群安装

环境规划 实际的生产使用中&#xff0c;我们一般推荐搭建奇数多节点的zookeeper集群&#xff0c;如3/5/7。在本次测试中&#xff0c;我使用了centos7 三台服务器搭建&#xff0c;复用了我搭建k8s集群的环境&#xff0c;如下表。 IPhostname192.168.2.140k8s-m1192.168.2.141k…...

CUDA小白 - NPP(2) - Arithmetic and Logical Operations(1)

cuda小白 原文链接 NPP GPU架构近些年也有不少的变化&#xff0c;具体的可以参考别的博主的介绍&#xff0c;都比较详细。还有一些cuda中的专有名词的含义&#xff0c;可以参考《详解CUDA的Context、Stream、Warp、SM、SP、Kernel、Block、Grid》 常见的NppStatus&#xff0c…...

计算机视觉-LeNet

目录 LeNet LeNet在手写数字识别上的应用 LeNet在眼疾识别数据集iChallenge-PM上的应用 LeNet LeNet是最早的卷积神经网络之一。1998年&#xff0c;Yann LeCun第一次将LeNet卷积神经网络应用到图像分类上&#xff0c;在手写数字识别任务中取得了巨大成功。LeNet通过连续使用…...

Java 复习笔记 - 面向对象篇

文章目录 一&#xff0c;面向对象概述二&#xff0c;类和对象&#xff08;一&#xff09;类和对象的概述&#xff08;二&#xff09;定义类的补充注意事项 三&#xff0c;封装四&#xff0c;就近原则和this关键字&#xff08;一&#xff09;就近原则&#xff08;二&#xff09;…...

淘宝虚拟商品选品实操:从儿童学习资料到游戏攻略的蓝海挖掘术

淘宝虚拟商品选品高阶指南&#xff1a;从儿童教育到游戏产业的精细化运营策略 在淘宝虚拟商品领域&#xff0c;真正能够持续盈利的卖家往往不是那些追逐热门品类的跟风者&#xff0c;而是懂得在细分市场中寻找差异化机会的"蓝海猎手"。儿童学习资料和游戏攻略这两个看…...

Rust Web开发:ActixWeb实战指南

1. 为什么选择ActixWeb进行Rust Web开发 我第一次接触ActixWeb是在三年前的一个电商项目里&#xff0c;当时团队需要处理每秒上万次的库存查询请求。测试了多个Rust框架后&#xff0c;ActixWeb凭借其卓越的性能表现脱颖而出——在同等硬件条件下&#xff0c;它的QPS&#xff08…...

终极英雄联盟工具集:3大核心功能让你轻松掌控游戏全局

终极英雄联盟工具集&#xff1a;3大核心功能让你轻松掌控游戏全局 【免费下载链接】League-Toolkit 兴趣使然的、简单易用的英雄联盟工具集。支持战绩查询、自动秒选等功能。基于 LCU API。 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit League-Toolkit…...

Windows 10终极指南:免费开启HEIC缩略图预览功能

Windows 10终极指南&#xff1a;免费开启HEIC缩略图预览功能 【免费下载链接】windows-heic-thumbnails Enable Windows Explorer to display thumbnails for HEIC files 项目地址: https://gitcode.com/gh_mirrors/wi/windows-heic-thumbnails 还在为iPhone拍摄的照片在…...

Gemma-3-270m多场景落地:政务热线知识库问答、医疗术语解释系统

Gemma-3-270m多场景落地&#xff1a;政务热线知识库问答、医疗术语解释系统 1. 快速上手&#xff1a;部署你的第一个Gemma-3-270m服务 想要快速体验Gemma-3-270m的强大能力&#xff1f;通过Ollama部署只需几个简单步骤。 1.1 环境准备与模型选择 首先确保你已经安装了Ollam…...

ArduinoLog:面向MCU的零开销C++嵌入式日志框架

1. ArduinoLog 项目概述ArduinoLog 是一款专为 Arduino 及兼容嵌入式平台&#xff08;包括 AVR、SAM、ESP8266 等&#xff09;设计的轻量级 C 日志框架。其核心设计哲学是“零运行时开销、零动态内存分配、全编译期可控”&#xff0c;在资源极度受限的微控制器环境中&#xff0…...

车载Android Auto兼容性开发全链路(车规级Java SDK集成手册)

第一章&#xff1a;车载Android Auto兼容性开发全链路概览Android Auto 是 Google 提供的车载信息娱乐系统集成框架&#xff0c;其兼容性开发并非仅限于应用层适配&#xff0c;而是一条横跨设备端、车机系统、认证流程与用户交互的完整技术链路。开发者需同步关注 Android 应用…...

使用seo站点管理系统需要注意哪些事项

SEO站点管理系统的核心注意事项 在当今数字化时代&#xff0c;SEO站点管理系统&#xff08;Site Management System for SEO&#xff09;是网站运营和推广的关键工具。它不仅能帮助提升网站在搜索引擎中的排名&#xff0c;还能带来更多的流量和转化。要真正利用这一工具&#x…...

增程式混合动力汽车MATLAB_simulink模型(串联)整车建模包括工况选择模型、驾驶员模型(PID控制)、整车工作模式控制模型、发动机模型、电机模型、电池模型、传动系统模型、整车动力学模型。

增程式混合动力汽车MATLAB/simulink模型&#xff08;串联&#xff09;整车建模包括工况选择模型、驾驶员模型&#xff08;PID控制&#xff09;、整车工作模式控制模型、发动机模型、电机模型、电池模型、传动系统模型、整车动力学模型。 此模型比较简单&#xff0c;当SOC低于SO…...

创维E900V22D_S905L3S(B)芯片-安卓9.0-免拆线刷固件包及短接神器使用指南

1. 创维E900V22D刷机前的准备工作 拿到创维E900V22D机顶盒的第一件事&#xff0c;就是确认它的硬件配置。这个型号采用的是晶晨S905L3S(B)芯片方案&#xff0c;运行的是安卓9.0系统。我遇到过不少朋友因为没看清芯片型号就开刷&#xff0c;结果把盒子刷成砖的案例。所以一定要先…...