最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 前端之变(六):引领式变革,从命令式UI到声明式UI

    正文概述 掘金(御剑_lingen)   2021-07-04   554

    当我在2020年使用前端的技术栈去编写一个跨平台桌面App时,发现前端在UI方面其模式与我在移动端接触到的有很大的差异,那时候我意识到原来在前端,其UI使用的是另一种模式,后面我才知道它的名字:声明式UI

    事实上,前端本身也经历了变革,至少在JQuery时代,它与移动端一致,其UI模式仍然属于传统的命令式UI,但到了React及Vue的时代,它变成了声明式UI。从我有限的知识来看,至少在大前端的其它两个方向:移动端与桌面开发,并未优先引领式的出现这种变革。

    因此,我把前端的这种变革,称之为:引领式变革

    它改变的不仅仅是自己。而且正在改变移动端,无论是Android官方自己主推的Jetpack,还是iOS官方新的UI框架SwiftUI,与之前也完全不同,都从命令式UI变为声明式UI。很难说这种变革,没有受到前端的影响或借鉴。

    这说明前端技术变革不仅改变了自身,甚至在一些方面走在了更前面。

    本周,继续就前端之变阐述自己的思考与分析。这是第六篇。前面几篇分别是:

    1. 前端之变(一):技术的变与不变
    2. 前端之变(二): "不变"的前端
    3. 前端之变(三):变革与突破
    4. 前端之变(四):进击的前端
    5. 前端之变(五):王者归来

    命令式与声明式

    首先,要明确一个前提,UI这个事情,只在大前端才有。所以,无论是命令式UI还是声明式UI,在后端编码是不存在这个概念的。

    当然,若干年前,后端兼顾前端页面的开发,但那个时代已经过去了。现在主流的模式应该是前后端分离,由后端人员同时来开发前端,比如用JSP或FreeMarker模板技术的做法,在现在应该不多见了,不能算主流了。

    UI这个事情并非只在Web前端才有,事实上,在技术的几个方向,除了后端以外,包括前端,移动端及桌面端都存在UI。

    因此,无论是命令式UI,还是声明式UI,其概念是同时适应于前端,移动端以及桌面端的。

    在这个前提之下,我们就可以来仔细分析下,在前端发生变革以前,事实上无论是在前端,移动端还是桌面端,其UI的编码模式都属于命令式UI

    UI的更新是由程序员使用代码主动刷新,UI与数据并无必然的映射关系,这种我们称之为命令式UI

    UI的更新并非由程序员使用代码来主动刷新,而是由后面隐藏机制来负责维护UI的刷新,UI与数据有映射关系,这种我们就称之为声明式UI

    上面这种定义是我的定义,根据上述定义,区分是命令式UI还是声明式UI的两个核心点是:

    1. 程序员是否要显式的去调用代码刷新UI
    2. 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的最核心的区别在于:

    1. UI是数据的映射与描述,甚至一些框架中,程序员是无法持有UI组件的。更谈不上去调用这个组件的方法刷新UI了。
    2. 程序员关心的只是数据,只需要在合适的时机刷新数据就行了。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的未来的准备。

    前端之困

    前端发生了巨大的变革,如我所言,这种变化是革命性的,颠覆性的。

    但从我在前端的经验来看,无论是前端语言的生态,还是质量,与后端仍存在一些差距,这就非常值得我的思考,如果理念与技术并没有问题,那问题究竟在哪?

    下一篇,前端之变(七):前端之困,继续就前端阐述我的思考与分析。


    起源地下载网 » 前端之变(六):引领式变革,从命令式UI到声明式UI

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元