网站首页 > 技术文章 正文
当我在2020年使用前端的技术栈去编写一个跨平台桌面App时,发现前端在UI方面其模式与我在移动端接触到的有很大的差异,那时候我意识到原来在前端,其UI使用的是另一种模式,后面我才知道它的名字:声明式UI
事实上,前端本身也经历了变革,至少在JQuery时代,它与移动端一致,其UI模式仍然属于传统的命令式UI,但到了React及Vue的时代,它变成了声明式UI。从我有限的知识来看,至少在大前端的其它两个方向:移动端与桌面开发,并未优先引领式的出现这种变革。
因此,我把前端的这种变革,称之为:引领式变革。
它改变的不仅仅是自己。而且正在改变移动端,无论是Android官方自己主推的Jetpack,还是iOS官方新的UI框架SwiftUI,与之前也完全不同,都从命令式UI变为声明式UI。很难说这种变革,没有受到前端的影响或借鉴。
这说明前端技术变革不仅改变了自身,甚至在一些方面走在了更前面。
本周,继续就前端之变阐述自己的思考与分析。这是第六篇。前面几篇分别是:
命令式与声明式
首先,要明确一个前提,UI这个事情,只在大前端才有。所以,无论是命令式UI还是声明式UI,在后端编码是不存在这个概念的。
当然,若干年前,后端兼顾前端页面的开发,但那个时代已经过去了。现在主流的模式应该是前后端分离,由后端人员同时来开发前端,比如用JSP或FreeMarker模板技术的做法,在现在应该不多见了,不能算主流了。
UI这个事情并非只在Web前端才有,事实上,在技术的几个方向,除了后端以外,包括前端,移动端及桌面端都存在UI。
因此,无论是命令式UI,还是声明式UI,其概念是同时适应于前端,移动端以及桌面端的。
在这个前提之下,我们就可以来仔细分析下,在前端发生变革以前,事实上无论是在前端,移动端还是桌面端,其UI的编码模式都属于命令式UI
什么是命令式UI
UI的更新是由程序员使用代码主动刷新,UI与数据并无必然的映射关系,这种我们称之为命令式UI
什么是声明式UI
UI的更新并非由程序员使用代码来主动刷新,而是由后面隐藏机制来负责维护UI的刷新,UI与数据有映射关系,这种我们就称之为声明式UI
上面这种定义是我的定义,根据上述定义,区分是命令式UI还是声明式UI的两个核心点是:
- 程序员是否要显式的去调用代码刷新UI
- UI与数据是否存在映射关系
传统UI模式:命令式UI
我们回到过往的时光,在那个还是JQuery主导前端开发的时代,我们设想一个最简单的需求:记住上一次的登录用户名
我在这里用前端与移动端的代码来示例,展现命令式UI的做法:
前端
//基于JQuery的实现
const lastLoginUsername = localstorage.getItem("lastLoginUsername")
$("#username").val(lastLoginUsername);//主动刷新UI
移动端
//Android + Java
String lastLoginUsername = preferences.getString("lastLoginUsername", "");
usernameInput.setText(lastLoginUsername);//主动刷新UI
上述的这些实现,就是典型的命令式UI,它都具备几个特点:
- 在程序中,你可以显式的引用或拿到UI组件
- UI组件的内容是怎么样,什么时候改变内容,都是由程序员在合适的时候进行处理。UI本身与数据并无直接的映射关联,都是由程序员将数据显式的注入到UI中。
无论是传统的前端开发,还是我前些年开发原生iOS与Android,都统一属于这种模式。它们都毫不例外地属于命令式UI。
这种命令式UI的模式,是存在一些问题的,表现在:
UI维护工作较重
从上面我的描述可以看出,整体UI行为,怎么样,什么时候怎么改变,要全部由程序员使用代码来处理。可想而知,这个过程显然是非常繁重的。事实上,可以说,无论是过往的前端,还是现在的移动端,可能有相当一部分工作都是在处理UI的各种刷新上面。
易于出错
很显然,需要刷新UI的时机很多,比如下拉刷新,通知数据变更,网络不好数据加载错误,其它模块变更引发的联动UI变更等等,很多情况下需要你处理UI的刷新工作。
需要处理的事情一旦多起来,出错的概率就再所难免了。
性能不佳
通过一个UI包含很多内容与组件,但需要刷新时,你是怎么处理刷新的?
是不管三七二十一,将所有UI内容全部设置一下,还是先对比下,有改变的再刷新,没改变的不再刷新?
可能有相当一部分比例,是属于全部设置一下的做法。这种的性能肯定不会太好,产生了许多不必要刷新。
当然,如果你比对然后只尽量做必要性的刷新,那这个事也有相当的复杂度的,而且可能易于出错。
UI与数据易出现不一致
想象一下吧,你的代码中有一份数据,这份数据决定了UI的展现,但事实上程序员是分开处理这两个部分的,由一些代码来调用刷新数据,再由一些方法现刷新UI,无论你做的多么周到,出现数据变更 ,UI却忘记刷新的可能性仍然是非常高的。
因此,UI与数据出现不一致的可能性极高。
所幸,声明式UI出现了,它极大的改善了这些问题。
变革之道:声明式UI
声明式UI与命令式UI的最核心的区别在于:
- UI是数据的映射与描述,甚至一些框架中,程序员是无法持有UI组件的。更谈不上去调用这个组件的方法刷新UI了。
- 程序员关心的只是数据,只需要在合适的时机刷新数据就行了。UI则根据映射,由技术背后的机制帮你去刷新处理。
很显然,这是对命令式UI做了根本性的改变。
我在这举一个简单的例子,仍然以记住上一次登录用户这个需求为例。
//代码做了删减,只保留了有关的部分
export const LoginView = observer(() => {
const [username, setUsername] = useState(localStorage.getItem('login_username'));
return (
<Input className="input_username" value={username} onChange={e => setUsername(e.target.value)} />
);
});
这是一个React代码,你可以看到,input_username这个输入框的值是{username}这个变量,而要修改这个输入框的值的方式,也不是调用UI的方法去设置值,而是通过改变username这个变量来实现。
所以,修改这个UI的内容的方法是
onChange={e => setUsername(e.target.value)}
一旦你改变了username的值,input_username的内容自动的刷新改变了,并不需要程序员去介入UI的刷新工作。
这就是声明式UI
声明式UI如果要论述,可以说得很多,我这篇文章的目的不在于此。就不详细去解释它了。
当然,很明显,与命令式UI相比,上述的几个缺点都有所改善:
程序员没有复杂的UI操作
在声明式UI中,程序员要做的就是定义数据与UI的映射关系而已,一旦定义好后,后面只需要关心数据的维护,不需要再关心UI的刷新了,这极大的减轻了程序员的在UI上的工作。
事实上,以我个人编写移动端与前端的经历来看,前端的UI编写的确更快,更有效率
难以出错
显而易见的是吧,UI刷新是由框架或技术背后实现的,你只需要刷新数据就可以了,框架或技术的可靠性保证了不太可能出现数据刷新了,UI却没刷新或刷新出错的情况。
极高的性能
由于对数据的映射与刷新是框架在背后处理的,通过大部分框架都不会数据一变就全量刷新,这就太low了。
比如,React就有一个diff算法,这个算法保证了只进行必要的刷新,这是非常高效的做法。
UI与数据的一致性
你只需要关心数据,变更数据。并不需要担心数据与UI出现不一致的情况。
在框架质量有所保证的前提下,这种可能几乎为小的可以忽略不计。(框架也可能有BUG,不能期望它为0)
趋势,大前端UI的未来
当然,『后』前端阶段,无论是React或Vue,都已经是这种声明式UI的做法了,它已经是前端的事实与主流了。
而在移动端,Android现在本身主推的是Jetpack,而iOS主推的是SwiftUI,这些也都是声明式UI了。但在移动端,它们仍然只是趋势,移动端现在绝大部分主流可能仍然是过往的命令式UI。
但可想而知,就算移动端,未来也必然会转向声明式UI。
至于移动端非原生的技术,类似Flutter,React Native等就不用说了,这些已经是声明式UI的实现了。
至于桌面端,由于我只有基于Electron开发桌面软件的经验,这是个前端技术,当然也是声明式UI,至于原生Window或Linux桌面开发,我并未有相关经验,但我相信借鉴声明式UI也绝对是正确的趋势。
所以,做为一个大前端的程序员,无论你是前端或是移动端,还是桌面端,你都要做好迎接声明式UI的未来的准备。
前端之困
前端发生了巨大的变革,如我所言,这种变化是革命性的,颠覆性的。
但从我在前端的经验来看,无论是前端语言的生态,还是质量,与后端仍存在一些差距,这就非常值得我的思考,如果理念与技术并没有问题,那问题究竟在哪?
下一篇,前端之变(七):前端之困,继续就前端阐述我的思考与分析。
猜你喜欢
- 2024-11-20 英文UI界面第三波了,每次欣赏都感觉收获满满!
- 2024-11-20 官网想要吸引住用户,首屏设计必须出彩。
- 2024-11-20 移动UI排行榜页面,既要有创意又要一目了然。
- 2024-11-20 英文界面换成中文就拉胯,其实未必,看过来。
- 2024-11-20 AI界面的对比图_:文心一言、豆包、通义千问
- 2024-11-20 想要转行Java、web前端、UI设计的小伙伴不用纠结且迷茫了
- 2024-11-20 移动UI的排行榜设计好了,你追我赶的氛围就有了!
- 2024-11-20 这炫酷的ui设计放到app里那还不是直接起飞了
- 2024-11-20 后端瞧不上前端,还不是吃了B端UI框架的红利。
- 2024-11-20 极易导致前端和UI互撕的可视化界面
你 发表评论:
欢迎- 07-10Oracle 与 Google Cloud 携手大幅扩展多云服务
- 07-10分享收藏的 oracle 11.2.0.4各平台的下载地址
- 07-10Oracle 和 Microsoft 推出 Oracle Exadata 数据库服务
- 07-10Oracle Database@Azure 推进到南美等新区域并增加了新服务
- 07-10Oracle宣布推出 Oracle Database@AWS 的有限预览版
- 07-10Oracle与Nextcloud合作,推出主权云上的安全协作平台
- 07-10NodeRED魔改版连接MsSql、PostgreSQL、MySQL、OracleDB存储无忧
- 07-10对于企业数据云备份,“多备份”承诺的是成本更低,管理更高效#36氪开放日深圳站#
- 602℃几个Oracle空值处理函数 oracle处理null值的函数
- 594℃Oracle分析函数之Lag和Lead()使用
- 582℃0497-如何将Kerberos的CDH6.1从Oracle JDK 1.8迁移至OpenJDK 1.8
- 579℃Oracle数据库的单、多行函数 oracle执行多个sql语句
- 574℃Oracle 12c PDB迁移(一) oracle迁移到oceanbase
- 568℃【数据统计分析】详解Oracle分组函数之CUBE
- 554℃最佳实践 | 提效 47 倍,制造业生产 Oracle 迁移替换
- 548℃Oracle有哪些常见的函数? oracle中常用的函数
- 最近发表
-
- Oracle 与 Google Cloud 携手大幅扩展多云服务
- 分享收藏的 oracle 11.2.0.4各平台的下载地址
- Oracle 和 Microsoft 推出 Oracle Exadata 数据库服务
- Oracle Database@Azure 推进到南美等新区域并增加了新服务
- Oracle宣布推出 Oracle Database@AWS 的有限预览版
- Oracle与Nextcloud合作,推出主权云上的安全协作平台
- NodeRED魔改版连接MsSql、PostgreSQL、MySQL、OracleDB存储无忧
- 对于企业数据云备份,“多备份”承诺的是成本更低,管理更高效#36氪开放日深圳站#
- 解读丨《归档文件整理规则》— 电子文件元数据存储
- Data Guard跳归档恢复的实践(dataguard failover)
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端aes加密 (58)
- 前端脚手架 (56)
- 前端md5加密 (54)
- 前端路由 (61)
- 前端数组 (73)
- 前端js面试题 (50)
- 前端定时器 (59)
- 前端获取当前时间 (50)
- Oracle RAC (76)
- oracle恢复 (77)
- oracle 删除表 (52)
- oracle 用户名 (80)
- oracle 工具 (55)
- oracle 内存 (55)
- oracle 导出表 (62)
- oracle约束 (54)
- oracle 中文 (51)
- oracle链接 (54)
- oracle的函数 (57)
- 前端调试 (52)
本文暂时没有评论,来添加一个吧(●'◡'●)