大神一篇文,胜读十年书,小白看完都学会了

2024-02-08 20:20

本文主要是介绍大神一篇文,胜读十年书,小白看完都学会了,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

三、 编程开发

React Native 使用的 JavaScript 相信大家都不陌生,已经 24 岁的它在多年的发展过程中,各端各平台中都出没着它的身影,在 Facebook 的 React 开始风靡之后,15 年移动浪潮下推出的 React Native ,让前端的 JS 开发者拥有了技能的拓展。

Flutter 的首选语言 Dart 语言诞生于 2011 年,而 2018 年才发布了 2.0,原本是为了用来对抗 JavaScript 而发布的开发语言,却在 Web 端一直不温不火,直到 17年 才因为 Flutter 而受关注起来,之后又因为 Flutter For Web 继续尝试后回归 Web 领域。

编程开发所涉及的点较多,后面主要从 开发语言 、界面开发 、状态管理 、原生控件 四个方面进行对比介绍。

至于最多吐槽之一就是为什么 Flutter 团队不选择 JS ,有说因为 Dart 团队就在 Flutter 团队隔壁,也有说谷歌不想和 Oracle 相关的东西沾上边。 同时 React Native 更新快 4 年了,版本号依旧没有突破 1.0 。

3.1、 语言

因为起初都是为了 Web 而生,所以 Dart 和 JS 在一定程度上有很大的通识性。

如下代码所示, 它们都支持通过 var 定义变量,支持 async/await 语法糖,支持 Promise(Future) 等链式异步处理,甚至 */yield 的语法糖都类似(虽然这个对比不大准确),但可以看出它们确实存在“近亲关系” 。


/// JSvar a = 1async function doSomeThing() {var result = await xxxx()doAsync().then((res) => {console.log("ffff")})}function* _loadUserInfo () {console.log("**********************");yield put(UpdateUserAction(res.data));}/// Dartvar a = 1;void doSomeThing() async {var result = await xxxx();doAsync().then((res) {print('ffff');});}_loadUserInfo() async* {print("**********************");yield UpdateUserAction(res.data);}

但是它们之间的差异性也很多,而最大的区别就是: JS 是动态语言,而 Dart 是伪动态语言的强类型语言。

如下代码中,在 Dart 中可以直接声明 name 为 String 类型,同时 otherName 虽然是通过 var 语法糖声明,但在赋值时其实会通过自推导出类型 ,而 dynamic 声明的才是真的动态变量,在运行时才检测类型。

// DartString name = 'dart'; 
var otherName = 'Dart';
dynamic dynamicName = 'dynamic Dart'; 

如下图代码最能体现这个差异,在下图例子中:

  • var i 在全局中未声明类型时,会被指定为 dymanic ,从而导致在 init() 方法中编译时不会判断类型,这和 JS 内的现象会一致。

  • 如果将 var i = ""; 定义在 init() 方法内,这时候 i 已经是强类型 String了 ,所以编译器会在 i++报错,但是这个写法在 JS 动态语言里,默认编译时是不会报错的。

动态语言和非动态语言都有各种的优缺点,比如 JS 开发便捷度明显会高于 Dart ,而 Dart 在类型安全和重构代码等方面又会比 JS 更稳健。

3.2、界面开发

React Native 在界面开发上延续了 React 的开发风格,支持 scss/sass 、样式代码分离、在 0.59 版本开始支持 React Hook 函数式编程 等等,而不同 React 之处就是更换标签名,并且样式和属性支持因为平台兼容做了删减。

如下图所示,是一个普通 React Native 组件常见实现方式,继承 Component 类,通过 props 传递参数,然后在 render 方法中返回需要的布局,布局中每个控件通过 style 设置样式 等等,这对于前端开发者基本上没有太大的学习成本。

如下所示,如果再配合 React Hooks 的加持,函数式的开发无疑让整个代码结构更为简洁。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0PjTL5K7-1631769372064)(https://upload-images.jianshu.io/upload_images/23587538-a7a1e4128cd7a3d6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]

Flutter 最大的特点在于: Flutter 是一套平台无关的 UI 框架,在 Flutter 宇宙中万物皆 Widget

如下图所示,Flutter 开发中一般是通过继承 无状态 StatelessWidget 控件或者 有状态 StatefulWidget 控件 来实现页面,然后在对应的 Widget build(BuildContext context) 方法内实现布局,利用不同 Widget 的 child / children 去做嵌套,通过控件的构造方法传递参数,最后对布局里的每个控件设置样式等。

而对于 Flutter 控件开发,目前最多的吐槽就是 控件嵌套和样式代码不分离 ,样式代码分离这个问题我就暂不评价,这个真要实际开发才能更有体会,而关于嵌套这里可以做一些 “洗白” :

Flutter 中把一切皆为 Widget 贯彻得很彻底,所以 Widget 的颗粒度控制得很细 ,如 Padding 、Center 都会是一个单独的 Widget,甚至状态共享都是通过 InheritedWidget 共享 Widget 去实现的,而这也是被吐槽的代码嵌套样式难看的原因。

事实上正是因为颗粒度细,所以你才可以通过不同的 Widget , 自由组合出多种业务模版, 比如 Flutter 中常用的 Container ,它就是官方帮你组合好的模板之一, Container 内部其实是由 Align、 ConstrainedBox 、DecoratedBox 、Padding 、Transform 等控件组合而成 ,所以嵌套深度等问题完全是可以人为控制,甚至可以在帧率和绘制上做到更细致的控制。

当然,官方也在不断地改进优化编写和可视化的体验,如下图所示,从目前官方放出的消息上看,未来这个问题也会被进一步改善。

最后总结一下,抛开上面的开发风格,React Native 在 UI 开发上最大的特点就是平台相关,而 Flutter 则是平台无关,比如下拉刷新,在 React Native 中, <RefreshControl> 会自带平台的不同下拉刷新效果,而在 Flutter 中,如果需要平台不同下拉刷新效果,那么你需要分别使用 RefreshIndicator 和 CupertinoSliverRefreshControl 做显示,不然多端都会呈现出一致的效果。

3.3、状态管理

前面说过, Flutter 在很多方面都借鉴了 React Native ,所以在状态管理方面也极具“即视感”,比如都是调用 setState 的方式去更新,同时操作都不是立即生效的 ,当然它们也有着差异的地方,如下代码所示:

  • 正常情况下 React Native 需要在 Component 内初始化一个 this.state 变量,然后通过 this.state.name 访问 。
  • Flutter 继承 StatefulWidget ,然后在其的 State 对象内通过变量直接访问和 setState 触发更新。
/// JSthis.state = {name: ""};···this.setState({name: "loading"});···<Text>this.state.name</Text>/// Dartvar name = "";setState(() {name =  "loading";});···Text(name)复制代码

当然它们两者的内部实现也有着很大差异,比如 React Native 受 React diff 等影响,而 Flutter 受 isRepaintBoundary 、markNeedsBuild 等影响。

而在第三方状态管理上,两者之间有着极高的相似度,如早期在 Flutter 平台就涌现了很多前端的状态管理框架如:[flutter_redux](

) 、[fish_redux](

) 、 [dva_flutter](

) 、[flutter_mobx](

) 等等,它们的设计思路都极具 React 特色。

同时 Flutter 官方也提供了 [scoped_model](

) 、[provider](

) 等具备 Flutter 特色的状态管理。

所以在状态管理上 React Native 和 Flutter 是十分相近的,甚至是在跟着 React 走。

3.4、原生控件

在跨平台开发中,就不得不说到接入原有平台的支持,比如 在 Android 平台上接入 x5 浏览器 、接入视频播放框架、接入 Lottie 动画框架等等。

这一需求 React Native 先天就支持,甚至在社区就已经提供了类似 [lottie-react-native](

) 的项目。 因为 React Native 整个渲染过程都在原生层中完成,所以接入原有平台控件并不会是难事 ,同时因为发展多年,虽然各类第三方库质量参差不齐,但是数量上的优势还是很明显的。

而 Flutter 在就明显趋于弱势,甚至官方在开始的时候,连 WebView 都不支持,这其实涉及到 Flutter 的实现原理问题。

因为 Flutter 的整体渲染脱离了原生层面,直接和 GPU 交互,导致了原生的控件无法直接插入其中 ,而在视频播放实现上, Flutter 提供了外界纹理的设计去实现,但是这个过程需要的数据转换,很明显的限制了它的通用性, 所以在后续版本中 Flutter 提供了 PlatformView 的模式来实现集成。

以 Android 为例子,在原生层 Flutter 通过 Presentation 副屏显示的原理,利用 VirtualDisplay 的方式,让 Android 控件在内存中绘制到 Surface 层。 VirtualDisplay 绘制在 Surface 的 textureId ,之后会通知到 Dart 层,在 Dart 层利用 AndroidView 定义好的 Widget 并带上 textureId ,那么 Engine 在渲染时,就会在内存中将 textureId 对应的数据渲染到 AndroidView 上。

PlatformView 的设计必定导致了性能上的缺陷,最大的体现就是内存占用的上涨,同时也引导了诸如键盘无法弹出[#19718](

)和黑屏等问题,甚至于在 Android 上的性能还可能不如外界纹理。

所以目前为止, Flutter 原生控件的接入上是仍不如 React Native 稳定。

四、 插件开发

React Native 和 Flutter 都是支持插件开发,不同在于 **React Native 开发的是 [npm](

) 插件,而 Flutter 开发的是 [pub](

) 插件。**

React Native 使用 npm 插件的好处就是:可以使用丰富的 npm 插件生态,同时减少前端开发者的学习成本。

但是使用 npm 的问题就是太容易躺坑,因为 npm 包依赖的复杂度和深度所惑,以至于你都可能不知道 npm 究竟装了什么东西,抛开安全问题,这里最直观的感受就是 :“为什么别人跑得起来,而我的跑不起来?” 同时每个项目都独立一个 node_module ,对于硬盘空间较小的 Mac 用户略显心酸。

Flutter 的 pub 插件默认统一管理在 pub 上,类似于 npm 同样支持 git 链接安装,而 flutter packages get 文件一般保存在电脑的统一位置,多个项目都引用着同一份插件。

  • win 一般是在 C:\Users\xxxxx\AppData\Roaming\Pub\Cache 路径下
  • mac 目录在 ~/.pub-cache

如果找不到插件目录,也可以通过查看 .flutter-plugins 文件,或如下图方式打开插件目录。

最后说一下 Flutter 和 React Native 插件,在带有原生代码时不同的处理方法:

  • React Native 在安装完带有原生代码的插件后,需要执行 react-native link 脚本去引入支持,具体如 Android 会在 setting.gradle 、 build.gradle 、MainApplication.java 等地方进行侵入性修改而达到引用。

  • Flutter 则是通过 .flutter-plugins 文件,保存了带有原生代码的插件 key-value 路径 ,之后 Flutter 的脚本会通过读取的方式,动态将原生代码引入,最后通过生成 GeneratedPluginRegistrant.java 这个忽略文件完成导入,这个过程开发者基本是无感的。

所以在插件这一块的体验, Flutter 是略微优于 React Native 的。

五、 编译和产物

React Native 编译后的文件主要是 bundle 文件,在 Android 中是 index.android.bunlde 文件,而在 IOS 下是 main.jsbundle 。

总结:

各行各样都会淘汰一些能力差的,不仅仅是IT这个行业,所以,不要被程序猿是吃青春饭等等这类话题所吓倒,也不要觉得,找到一份工作,就享受安逸的生活,你在安逸的同时,别人正在奋力的向前跑,这样与别人的差距也就会越来越遥远,加油,希望,我们每一个人,成为更好的自己。

  • **[CodeChina开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》](

)**

  • BAT大厂面试题、独家面试工具包,

  • 资料包括 数据结构、Kotlin、计算机网络、Framework源码、数据结构与算法、小程序、NDK、Flutter,


    这样与别人的差距也就会越来越遥远,加油,希望,我们每一个人,成为更好的自己。

  • **[CodeChina开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》](

)**

  • BAT大厂面试题、独家面试工具包,

  • 资料包括 数据结构、Kotlin、计算机网络、Framework源码、数据结构与算法、小程序、NDK、Flutter,

    [外链图片转存中…(img-Csqt59OY-1631769372071)]

这篇关于大神一篇文,胜读十年书,小白看完都学会了的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/692105

相关文章

为何我建议你学会抄代码?

文章目录 为何我建议你学会抄代码?一、引言二、抄代码的艺术1、理解抄代码的真正含义1.1、抄代码的好处 2、如何有效地抄代码2.1、发现问题2.2、整理需求2.3、造轮子标准流程 三、抄代码的实践案例1、发现问题2、整理需求3、设计重试机制4、实现重试工具类5、使用重试工具类6、优化和扩展 四、总结 为何我建议你学会抄代码? 一、引言 在编程的世界中,“抄代码” 常被视为一

CSP-J基础之数学基础 初等数论 一篇搞懂(一)

文章目录 前言声明初等数论是什么初等数论历史1. **古代时期**2. **中世纪时期**3. **文艺复兴与近代**4. **现代时期** 整数的整除性约数什么样的整数除什么样的整数才能得到整数?条件:举例说明:一般化: 判断两个数能否被整除 因数与倍数质数与复合数使用开根号法判定质数哥德巴赫猜想最大公因数与辗转相除法计算最大公因数的常用方法:举几个例子:例子 1: 计算 12 和 18

CSP-J基础之数学基础 初等数论 一篇搞懂(二)

文章目录 前言算术基本定理简介什么是质数?举个简单例子:重要的结论:算术基本定理公式解释:举例: 算术基本定理的求法如何找出质因数:举个简单的例子: 重要的步骤:C++实现 同余举个例子:同余的性质简介1. 同余的自反性2. 同余的对称性3. 同余的传递性4. 同余的加法性质5. 同余的乘法性质 推论 总结 前言 在计算机科学和数学中,初等数论是一个重要的基础领域,涉及到整数

作为刚从事Java开发的小白,需要掌握哪些技能

作为一个刚踏入Java开发世界的小白,面对各种技术和工具,你可能会觉得有点不知所措。但是别担心,我会给你一个简单清晰的路线图,让你可以有条不紊地掌握基本技能,逐步成长为一名Java开发者。 1. 扎实的Java基础 Java的基础是你迈向高级开发的重要基石,建议从以下几个方面着手: 语法和基础概念:比如变量、条件语句、循环、方法、数组、面向对象编程(OOP)等等。这些基础如同建房子的地基,越

【Linux】萌新看过来!一篇文章带你走进Linux世界

🚀个人主页:奋斗的小羊 🚀所属专栏:Linux 很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~ 目录 前言💥1、初识Linux💥1.1 什么是操作系统?💥1.2 各种操作系统对比💥1.3 现代Linux应用💥1.4 Linux常用版本 💥2、Linux 和 Windows 目录结构对比💥2.1 文件系统组织方式💥2.2

上海市计算机学会竞赛平台2024年7月月赛丙组求和问题

题目描述 给定 nn 个整数 a1,a2,…,ana1​,a2​,…,an​,请问这个序列最长有多少长的前缀,满足元素的和大于或等于 00?如果任何长度大于 00 的前缀之和都为负数,则输出 00 输入格式 第一行:单个整数表示 nn第二行:nn 个整数表示 a1,a2,…,ana1​,a2​,…,an​ 输出格式 单个整数:表示最长的前缀长度,使得前缀的和大于等于 00 数据范围

小白装修之全屋定制和软装

装修决策方法论:三点走下来 是则是 否则否 第一步:想清楚 哪些 是 真实需求 第二步: 了解这些需求是通过何种方式实现的 第三步:考虑 实现方式的缺点 是否能接受  全屋定制  方式:1.找全屋定制的商家  2.木工现场打柜子 组成:设计 + 板材 + 加工 + 配件 +安装 设计板块:明明有成品家具可以购买 为什么要做定制呢? 自主规划 选设计师 1.更符合我们房屋和物

科研小白成长记40——第三个五年计划

小gap期间,拼命玩和拼命休息的同时,仔细思考了下我期望的五年之后的样子,gap结束,算是目标愈发清晰起来。曾经,读博的目标是成为一名independent researcher,并且具备发至少一篇顶会的能力。而现在,希望五年后的自己,成为一名good independent researcher。当然,这里的good,根据现阶段的科研榜样,已经有了具体的metrics。 首先是随时在线的深度理解

上海市计算机学会竞赛平台2024年8月月赛丙组等差数列的素性

题目描述 给定三个整数 nn,aa 与 dd,表示一个项数为 nn 的等差数列,首项为 aa,公差为 dd。 请统计,从这个等差数列中有多少数字是素数 输入格式 三个整数: nn,aa 与 dd 输出格式 单个整数:表示素数数量 数据范围 50%50% 的数据,1≤n≤10001≤n≤1000100%100% 的数据,1≤n≤100001≤n≤100001≤d≤10001≤d≤10

【数据结构】你真的学会了二叉树了吗,来做一做二叉树的算法题及选择题

文章目录 1. 二叉树算法题1.1 单值二叉树1.2 相同的树1.3 另一棵树的子树1.4 二叉树的遍历1.5 二叉树的构建及遍历 2. 二叉树选择题3. 结语 1. 二叉树算法题 1.1 单值二叉树 https://leetcode.cn/problems/univalued-binary-tree/description/ 1.2 相同的树 https://leet