【Flutter、H5、Web?前端个人总结】分享从业经历经验、自我规范准则,纯干货
前言
hi,正式接触web前端已经经过了两年的时间,从大学的java后端转型到web前端,再到后续转战Flutter,逐渐对前端有了一些心得体会,其实在当下前端的呈现形式一直在变化,无论你是用原生、还是web还是混编的形式去做,我不希望前端被框架束缚住,它本质上不过是一种产品的表达形式罢了,是一种最靠近用户体验的实现方式
,所以这篇文章,在大体上来说,并不是针对于某一种框架或者技术栈,而是我想表达我在使用某一个呈现方式的时候对其的理解和体会,并尝试找出公共的特点,希望我的想法可能对你有一些帮助。
实现准备
一款产品往往来自于产品设计的某一个想法再到设计再经过一系列的流程最终转化成设计稿交付到前端的手上,那么这里面就有一系列需要前端有一系列的准备
,放心,不是让你提桶跑路,而是我认为大概率需要做的一些准备
沟通
沟通非常重要,一位优秀的产品设计师或许并不是优秀的前端实现者,他们考虑的并不是如何实现,而是真正把想法设计出来而已。我们需要考虑用户体验、人机交互、UI绘制、实现成本
,这其中往往存在一些矛盾的地方,这很正常,开发本身就是鱼翅熊掌很难兼得
的情况,重点是你需要把这些地方通过对话的方式
阐述出来。
举个例子,产品设计跳转动画非常的华丽,实现也能实现,但是时间成本比较高,在一些机型上甚至会出现卡顿的现象,用户体验差了,那么这种完全可以换一种实现方式,具体怎么换,换哪一种,是需要沟通商议出来的。
甚至有一些问题是在开发中途遇到的,这种时候也需要及时沟通(注释一定要写清楚,什么时候变更的,怎么变更的,谁指派的任务,可能会引起的后果)。
技术实现图
这一点对我而言也是非常重要的一环,可能某一些开发者拿到设计稿撸起袖子就是干,简单的设计流程可能还行,但是一旦遇到复杂的业务逻辑就开始手忙脚乱了,而且中间有一环错了,都不知道错误在哪里,后续代码更是难以维护,我们以苹果支付流程为例。
逻辑分层
对于复杂的业务逻辑,首先要做的是逻辑分层,先把大体流程做出来。
先把一步步的逻辑拆分出来,变成子任务,最后汇总成大体的业务逻辑。
设计画图
我们在把逻辑拆分出来之后,就要结合设计稿
,绘制我们的实现设计稿,比如我在实现苹果支付的流程就是如此,前者是逻辑思路的拆分,后者是用户看到的一面,真正给用户用到的功能图。
技术选型
这一点对于团队合作的项目来说十分重要,哪怕只有你一个人在开发,也要考虑后期的维护更新,又或者说是接替项目需要做技术方案更换,都需要考虑技术选型。
技术选型一般还需要考虑整体成本
,如果团队对某一个框架有很深的研究和理解,那自然选择理解最深的框架最好,时间成本最低,维护成本最低。
当然也需要看技术本身的持续性,官方生态是否齐全完善、论坛是否活跃、遇到问题是否有解决方案。
初步搭建
在进行技术选型之后,我们大概率要经历框架的搭建,这里主要考虑的可维护性和可拓展性
。
比如后续可能会被其他项目所使用,那么你可能要做成模块的形式。
比如后续可能会需要混淆代码、可能进行二次开发,那么你可能要做成基类的形式等等。
开发范式
这里主要是分享一些我个人的开发范式,当然可能企业内部有自己的代码规范,网上也有非常多的代码规范,所以这里不讲代码规范的东西,如果企业内部有,就遵从内部规范,如果没有就找靠谱的规范去走。
纯粹性
这里的纯粹性更多指的是组件或者函数没有副作用,比如你在开发一个页面的时候,可能某一个布局会被二次使用,这个时候大多数人会采用封装组件的形式,这样可以全局使用或者局部使用,不用二次编写造成冗余的代码,这一点没错,问题在于当组件不够纯粹可能造成的问题。
第一是数据依赖问题:
封装的时候,你需要弄清楚一点,你的组件究竟的作用是什么?
如果是纯粹的UI展示
,那么数据依赖大概率需要依赖于他的使用者
,它必须足够的纯粹,遵循着单向数据源
的原则。组件所有需要展示的数据来源于他的使用者,具体展示是根据拿到数据之后去呈现,一系列的交互数据都传递回使用者去处理,你的组件只负责展示,其余事情一概交给使用者
。
如果你不遵循这样的原则,组件的也能自己操作数据,那么数据的变化你是无法预测和追踪的,是不可控的。
我看过一个案例,使用flutter封装了一个静态组件,组件的某一处的ui依赖于某一个数据,但是这个数据是组件内部创建的,只是变化是由外部控制的,这个时候就有一个问题,当他页面刷新的时候,组件重置了,数据也重置了,尽量没有调用变化函数,但是ui还是变了,最终变成不可控不纯粹
的组件
后续改成所有变量、函数都由使用者进行传递,组件也就能按照预期的工作了。
第二是你只是想进行抽离,很大可能是这一块与当前的业务是无关的
,这个时候可以不遵循的单向数据源的原则,比如你只是想放一个广告展示着,数据是不会经常变动的,也不需要外部传递数据,它就跳转外部和关闭广告的功能,也不需要埋点。
分层
复杂项目代码尽量遵循MVM模型:
分层的目的更多的是为了提高代码的可维护性
- Web端
这个模型在web端更多体现在开发者个人层面,并没有代码层面上面的约束,也就是在web端你是足够"自由
"的。
比如我在做Vue2的项目或者Vue3,甚至React,你如果想抽离方法,Vue2你可能会使用mixin(当然非常不建议使用mixin,官方说的话确实是真的),Vue3或者React可能使用useHook的东西去自定义,也可以使用todo这些注释类的东西,这是因为框架本身就帮你做了很多东西,已经帮你分层了,暴露了一些操作数据就能引起UI变化的方法。
比如后端给了一个页面详情的json数据,它可能长这样
{"title":"这是标题","content":"这是内容","cover":"xxxxx.png"
}
然后它会体现在你的页面上来,你可能会说,这也太简单了吧。
拿到数据之后给页面的局部特殊变量(带有数据监听),直接赋值,页面监听到数据变化就会改变视图的呈现。
如果后端给的某一个变量,不是字符串类型,而是数字类型的,这个在编译之后都不会被察觉到,当然可能也不会报错,但这是无法被预测到的,你当然也可以选择使用Ts去增强代码的强度,毕竟在js方面分层的概念还是比较弱的。
- Flutter
Flutter我认为在这一块做得很好,本身就是强语言,对于类型的约束性是很强的,当然我在一开始接触的时候,还是非常痛苦的过程,不断的报错,可能结果就是已知的,但是编译器会强迫你去考虑未知的东西。
但是无论你用的是怎么样的框架我都建议你去进行分层,写一个伪代码。
实际上,对于语言而已,它并不知道或者说你要认为它是不知道,它可能会获取到怎么样的数据,你需要提前告诉它(模型)
定义好数据类型,定义数据转化方法,视图层并不是直接接触数据,而是先接触到我们的内部定义好的模型视图层,模型视图层来直接接触模型和视图,模型层才能接触到真正的数据。
- 编译器支持
当你这么做了之后,代码层面已经非常清楚将会拿到的是怎么样的数据,之后的代码提示会非常清晰,你对数据结构也会非常清晰 - 高度的可维护性
一旦数据出现问题或者数据结构发生了变化,你都能快速定位到相应的模型层去进行修改,由于视图和模型是相互依赖的关系,编译器也会快速的定位到需要修改的地方。
视图层也不会直接接触数据,而是接触视图模型层,所有的方法,变量,都在视图模型层去负责转化、分发,视图层纯粹的视图展示,模型纯粹的数据抽象化,这也体现了纯粹性的好处。无论你在前端或者在后端,对于复杂项目都请尽量这么做
容错
- 允许自己犯错
没有生来就完美的代码,哪怕是Vue的作者回顾几个月前的代码都会感概当初竟然会这么写,Vue已经被重写多遍了。如果不是核心部分受到伤害或者手眼可见的问题,请不要去想着如何优化。一是这会加重开发的心智负担,二是效率非常低,开发的同时去优化代码会让自己陷入自我怀疑的境地,走一步怕一步。先把逻辑写出来,再去敲代码,优化是后者的事情。 - 提高容错率
这里实际上是需要建立在前者的基础上的,只有你允许你犯错,才能提高容错率,先别急着反驳我,除非你能向我保证你从来都不犯错,只要键盘敲下就一定是最佳结果(如果是,那你可以跳过这一点)。
1、逻辑分层
只有将大体逻辑罗列出来,在后续的回顾中,才能从每一点逻辑中预测可能会发生什么错误,才能预防
2、视图分层
某一个视图专门负责展示某一块数据,尽量根据逻辑去拆分你的视图。
比如商城首页:
某一块都是单独的逻辑,不会因为一处地方有问题就影响全局,有问题既能够迅速定位,又能够快速迁移二次开发。
3、注释先别急着删除
前期的初版代码或许有不完美的地方、产品需求的变动等一系列原因导致你的代码发生了大的改动,这个时候你可能会删除旧逻辑代码,这一点本身没有问题,但是如果产品本身并不是特别稳定或者并没有经过长时间的琢磨或者沉淀的情况下,尽量不要去删除旧代码,谁知道呢?哪怕要删除,也一定要迭代几个稳定版本之后再慢慢去剔除掉。
官方为主
新人在接触新技术或者新框架的时候,可能会先去搜索视频、博客、文档去看,很少人能够直接阅读完整篇官方文档,我并不否认官方外的东西对开发的帮助,因为我也曾经这么尝试过。
官方文档可能在内容上比较繁多,但是一定是最准确的,如果不准确,就是这个技术已经不活跃了,或者根本没有阅读仔细。
外部资源也是在阅读理解了官方文档之后进行的拆解和分析,所以我会更推荐官方为主,其他资源为辅助的阅读方式
有demo先跑demo,从效果中去看代码再进一步看实现原理。
清理
在web端,浏览器自带有垃圾回收机制,对于无法访问到的数据可以判定为垃圾,当然也会因为操作不到,导致内存泄漏和变量污染的问题。在web端可能体现在定时器、计时器、自调用、错误使用全局变量等等情况。在Flutter端可能存在各种流数据,请求、变量等。
这里讲一个案例:
我们做的一款产品,是Flutter+h5的,某一些页面是用h5去做的,但是里面存在某一些数据是需要加密请求获取到的。我们一开始的方案是h5通知Flutter端进行请求,Flutter经过加密解密一些操作之后,将结果发送给h5端,如图所示:
正常来说是没有任何问题的,但是这里忽略了一个情况:
假如h5页面发出去请求之后,h5页面已经因为某一些原因已经卸载了,Flutter无感知,导致无法知道响应是否已经被接收到了,甚至可能有某一些业务需要重复调用请求,但是不知道h5已经无法处理了,Flutter也没有做好回收机制,导致请求满天飞的情况,无法中止的情况,当然如果是Dio本身就有提供回收机制的,但是你也需要注意这种情况,这又涉及到我之前的文章,在混编的情况下,请求究竟要放在哪里,但无论在哪里,你都要保证是可控的,否则就不要使用
升级
这里最好使用版本管理工具,例如nvm能管理node版本,fvm能管理flutter,那究竟是否要升级需要考虑以下几点:
- 升级了是否会影响旧版本的运行
- 新旧版本区别大不大
- 是不是必须要升级版本才能上线
- 升级了版本,导致旧版本无法运行,如何做好后期维护处理
结尾
写代码和构建 App 只是手段,并不是目的,学习技术的目的,也只是为了能通过解决问题而表现你的价值。
企业也不会在乎使用某一项技术有多么牛逼,他们看重的是技术能否以最小的成本换取背后最大化的收益
身体是革命的本钱
未完待续,欢迎评论补充和纠正
相关文章:

【Flutter、H5、Web?前端个人总结】分享从业经历经验、自我规范准则,纯干货
前言 hi,正式接触web前端已经经过了两年的时间,从大学的java后端转型到web前端,再到后续转战Flutter,逐渐对前端有了一些心得体会,其实在当下前端的呈现形式一直在变化,无论你是用原生、还是web还是混编的…...

mysql主从配置
一、准备工作 准备两个版本一致的数据库。 确认主库开启二进制日志,并配置server-id。 $ ##将 mysql的配置文件/home/mysql2/mysql/my.cnf 中关于二进制日志的配置 $ cd /home/mysql2/mysql/ $ vi my.cnf 修改如下 server-id 11 #log settings log_error erro…...

sklearn pipeline
示例代码 from sklearn.pipeline import Pipeline from sklearn.feature_extraction.text import CountVectorizer from sklearn.naive_bayes import MultinomialNB import numpy as np import scipy.linalg from sklearn.preprocessing import LabelEncoder, StandardScaler …...

springboot实现服务注册与发现
在Spring Boot应用中实现服务注册与发现通常使用Spring Cloud框架,其中Eureka和Consul是两个常用的服务注册与发现组件。以下是使用Eureka来实现服务注册与发现的基本步骤。 准备工作 添加依赖:在你的Spring Boot项目的pom.xml文件中添加Eureka相关的依…...

美格智能亮相2024中国移动全球合作伙伴大会,共赢AI+时代
2024年10月11日至13日,主题为“智焕新生 共创AI时代”的2024中国移动全球合作伙伴大会,在广州琶洲保利世贸博览馆召开,作为中国移动重要的战略合作伙伴,美格智能亮相4号馆E22展位,与上百家知名企业共同展示最新数智化创…...

【LeetCode】动态规划—309. 买卖股票的最佳时机含冷冻期(附完整Python/C++代码)
动态规划—309. 买卖股票的最佳时机含冷冻期 题目描述前言基本思路1. 问题定义2. 理解问题和递推关系状态定义:状态转移公式:初始条件: 3. 解决方法动态规划方法伪代码: 4. 进一步优化5. 小总结 Python代码Python代码解释总结 C代…...

IDE启动失败
报错:Cannot connect to already running IDE instance. Exception: Process 24,264 is still running 翻译:无法连接到已运行的IDE实例。异常:进程24,264仍在运行 打开任务管理器,找到PID为24264的CPU线程,强行结束即可。 【Ct…...

【Kubernetes】常见面试题汇总(六十)
目录 131. pod 一直处于 pending 状态? 132. helm 安装组件失败? 特别说明: 题目 1-68 属于【Kubernetes】的常规概念题,即 “ 汇总(一)~(二十二)” 。 题目 69-113 属于…...

maven dependency中scope的取值类型
在 Maven 中,<scope> 标签用于定义依赖项的范围,以指定依赖在不同阶段的可见性和生命周期。以下是 Maven 中常见的 <scope> 取值类型的详细介绍: 1. **compile**: - 默认的依赖范围,适用于编译、测试和…...

线性代数在大一计算机课程中的重要性
线性代数在大一计算机课程中的重要性 线性代数是一门研究向量空间、矩阵运算和线性变换的数学学科,在计算机科学中有着广泛的应用。大一的计算机课程中,线性代数的学习为学生们掌握许多计算机领域的关键概念打下了坚实的基础。本文将介绍线性代数的基本…...

笔记本电脑按住电源键强行关机,对电脑有伤害吗?
电脑卡住了,我们习惯性地按住电源键或者直接拔掉电源强制关机,但这种做法真的安全吗?会不会对电脑造成伤害呢? 其实,按住电源键关机和直接拔掉电源关机是不一样的。它们在硬件层面有着本质区别。 按住电源键关机 当…...

如何将 cryptopp库移植到UE5内
cryptopp是一个开源免费的算法库,这个库的用途非常多,我常常用这个库来做加解密的运算。这段时间在折腾UE5.4.4,学习的过程中,准备把cryptopp移植到游戏的工程内,但UE的编译环境和VS的编译环境完全不同,能在…...

SpringBoot 集成GPT实战,超简单详细
Spring AI 介绍 在当前的AI应用开发中,像OpenAI这样的GPT服务提供商主要通过HTTP接口提供服务,这导致大部分Java开发者缺乏一种标准化的方式来接入这些强大的语言模型。Spring AI Alibaba应运而生,它作为Spring团队提供的一个解决方案&…...

基于Langchain框架下Prompt工程调教大模型(LLM)[输入输出接口、提示词模板与例子选择器的协同应用
大家好,我是微学AI,今天给大家介绍一下基于Langchain框架下Prompt工程调教大模型(LLM)[输入输出接口、提示词模板与例子选择器的协同应用。本文深入探讨了Langchain框架下的Prompt工程在调教LLM(大语言模型)方面的应用,…...

Vue基于vue-office实现docx、xlsx、pdf文件的在线预览
文章目录 1、vue-office概述2、效果3、实现3.1 安装3.2 使用示例3.2.1 docx文档的预览3.2.2 excel文档预览3.2.3 pdf文档预览1、vue-office概述 vue-office是一个支持多种文件(docx、.xlsx、pdf)预览的vue组件库,支持vue2和vue3。 功能特色: 一站式:提供docx、.xlsx、pdf多…...

哪个软件可以在线编辑ppt? 一口气推荐5个做ppt的得力助手!
日常在制作ppt时,你是否经常遇到这些问题,ppt做到一半,电脑突然死机,来不及保存的ppt付之一炬,分分钟让人原地崩溃…… 好在许多团队也在持续跟进这个问题,给出了一个一劳永逸的最佳方案——PPT在线编辑&a…...

Django学习笔记九:Django中间件Middleware
Django中间件(Middleware)是一段在Django的请求/响应处理过程中,可以介入并改变请求或响应的代码。中间件是Django框架中一个非常强大的功能,它允许你在Django的视图函数之前或之后执行自定义代码。 中间件可以用于: …...

原来自媒体高手都是这样选话题的,活该人家赚大钱,真后悔知道晚了
做自媒体,话题是战略,内容是战术。 战略是要做正确的事情,战术是如何正确地做事。 如果战略上错误,战术上再勤奋努力都无济于事。 《孙子兵法》有云:“胜者先胜而后求战,败者先战而后求胜。” 相信很多…...

胤娲科技:AI绘梦师——一键复刻梵高《星空》
想象一下,你手中握有一张梵高的《星空》原图,只需轻轻一点,AI便能化身绘画大师,一步步在画布上重现那璀璨星河。 这不是科幻电影中的桥段,而是华盛顿大学科研团队带来的“Inverse Painting”项目,正悄然改变…...

第18课-C++继承:探索面向对象编程的复用之道
一、引言 C 作为一种强大的编程语言,继承机制在面向对象编程中扮演着至关重要的角色。它允许开发者基于已有的类创建新的类,从而实现代码的复用和功能的扩展。然而,继承的概念和使用方法并非一目了然,特别是在处理复杂的继承关系时…...

麒麟V10系统下的调试工具(网络和串口调试助手)
麒麟V10系统下的调试工具(网络和串口调试助手) 1.安装网络调试助手mnetassist arm64-main ①在linux下新建一个文件夹 mkdir /home/${USER}/NetAssist②将mnetassist arm64-main.zip拷贝到上面文件夹中,并解压给权限 cd /home/${USER}/Ne…...

ssh封装上传下载
pip install paramiko import paramikoclass SSHClient:def __init__(self, host, port, username, password):self.host = hostself.port = portself.username = usernameself.password = passwordself.ssh = Noneself.sftp = Nonedef connect(self):"""连接到…...

018_FEA_Structure_Static_in_Matlab结构静力学分析
刹车变形分析 本示例展示了如何使用 MATLAB 软件进行刹车变形分析。 这个例子是Matlab官方PDE工具箱的第一个例子,所需要的数据文件都由Matlab提供,包括CAD模型文件。 步骤 1: 导入 CAD 模型 导入 CAD 模型,这里使用的是一个带有孔的支架模…...

网页打不开、找不到服务器IP地址
现象:网络连接ok,软件能正常使用,当网页打不开。 原因:DNS 配置错误导致网站域名无法正确解析造成。 影响DNS设置的:VPN软件、浏览器DNS服务选择、IPv4属性被修改。 1、VPN代理未关闭 2、浏览器DNS解析选择 3、以太…...

RUM性能优化之图片加载
作者:三石 在现代Web开发中,图片作为内容表达的核心元素,其加载效率直接影响到页面的整体性能和用户体验。随着高清大图和动态图像的普及,优化图片加载变得尤为重要。RUM作为一种主动监测技术,能够帮助开发者从真实用户…...

【Java】—— 泛型:泛型的理解及其在集合(List,Set)、比较器(Comparator)中的使用
目录 1. 泛型概述 1.1 生活中的例子 1.2 泛型的引入 2. 使用泛型举例 2.1 集合中使用泛型 2.1.1 举例 2.1.2 练习 2.2 比较器中使用泛型 2.2.1 举例 2.2.2 练习 1. 泛型概述 1.1 生活中的例子 举例1:中药店,每个抽屉外面贴着标签 举例2&…...

【Python】selenium遇到“InvalidArgumentException”的解决方法
在使用try……except 的时候捕获到这个错误: InvalidArgumentException: invalid argument (Session info: chrome112.0.5614.0) 这个错误代表的是,当传入的参数不符合期望时,就会抛出这个异常: InvalidArgumentException: invali…...

RT-DETR改进策略:BackBone改进|CAFormer在RT-DETR中的创新应用,显著提升目标检测性能
摘要 在目标检测领域,模型性能的提升一直是研究者和开发者们关注的重点。近期,我们尝试将CAFormer模块引入RT-DETR模型中,以替换其原有的主干网络,这一创新性的改进带来了显著的性能提升。 CAFormer,作为MetaFormer框架下的一个变体,结合了深度可分离卷积和普通自注意力…...

【YOLOv11】ultralytics最新作品yolov11 AND 模型的训练、推理、验证、导出 以及 使用
目录 一 ultralytics公司的最新作品YOLOV11 1 yolov11的创新 2 安装YOLOv11 3 PYTHON Guide 二 训练 三 验证 四 推理 五 导出模型 六 使用 文档:https://docs.ultralytics.com/models/yolo11/ 代码链接:https://github.com/ultralytics/ult…...

动态规划——多状态动态规划问题
目录 一、打家劫舍 二、打家劫舍 II 三、删除并获得点数 四、粉刷房子 五、买卖股票的最佳时机含冷冻期 六、买卖股票的最佳时机含手续费 七、买卖股票的最佳时机III 八、买卖股票的最佳时机IV 一、打家劫舍 打家劫舍 第一步:确定状态表示 当我们每次…...