想得太简单
从没想过做前端开发的我,最近开始准备往全栈路上进发了。其实也不是从没有想过做一个全栈开发,只是觉得曾经的自己想的太过简单,入职上一家公司时曾经有过这样的“雄心壮志”,面试官问我:对自己将来的规划是什么?答曰:全栈开发。之后在这家公司待了有5个月,离开这家公司时的想法是:我把全栈开发想的太简单了。最终走之前访谈,我与之前进入公司时面谈的总经理聊天,说自己当时回答的太过幼稚,把全栈开发想象的太简单。而在这家公司的五个月,我实际上也没有进行过真正的前端开发,一直是在做后端。
改变认知
离开这家公司已经整整一年了,我又不得不踏上全栈之路,离开的一年,身心有了些新的变化,看了不少书,自觉得在软件开发领域的思维方式和学习方法上又进步了一点。开始学习前端开发,学习过后,发现自己之前想法太过于天真,当初在了解前端技术时,总觉需要完全领悟每个细节,但是计算机领域之广泛就决定了人们无法精通每样技术,只要具备理解核心要义的能力即可,现在对于新技术的学习以理解核心要义为准,不再纠缠于细节的边边角角,顿时觉得轻松许多,前端学习也就不觉得有什么压力了。
复盘开始
我一直认为学习后不总结(复盘),学习效果会大打折扣,总结过后总会收获更多,所以本篇文章是对最近所学前端的一点总结。
前端概览
前端领域直到今天的学习路径如下:简单花了两天时间通过网上免费的快速教程将HTML CSS JS过了一遍,然后花了一周多时间将React学习手册这本书看了一遍,最后网上搜索资料简单了解了前端的周边工具(npm webpack等)。共计花了大概有不到两周的时间,学习过程中有一些对前端的理解,在此写成文章,以作记录。另外说明下,我只是前端学习两周不到的一个门外汉,都是些粗浅理解,有经验的前端开发可以忽略本文,作为有一定编程基础的程序员姑且看之,有问题也可以相互交流。
前端技术
前端的核心就是HTML,不管浏览器显示什么都是通过解析HTML来实现的,CSS JS也必须在HTML来进行指定才能正常工作(不管是外部文件还是inline形式)。HTML是对前端界面的一种静态表示方式(如同代码与进程之间的关系),数据结构上看,HTML就是一个多叉树,而document对象(DOM)对应了HTML文本在浏览器内存中实际的数据结构,HTML和DOM对象是一一对应的映射关系,所以DOM对象也是树形结构存放在内存中的,浏览器将DOM对象绘制出来通过浏览器显示给用户,最终完成了HTML到浏览器界面呈现的整个过程。CSS从软件工程角度来看,我理解是用来分离职责的,理论上干掉CSS,一切描述用HTML实现也是没问题的,但是将CSS从HTML中抽象出来,是有利于样式的独立开发和复用的,所以用屁股想,像CSS这种模块化的设计,肯定也是有现成框架的。再谈JS,网上谈的已经够多,网页本身最早就是静态的HTML,那么动态HTML怎么实现呢?在客户端,就是用JS来实现,直接操作浏览器初始化的JS对象(操作最多的就是DOM对象),在服务端花样应该就比较多了,最朴素的方法的就是在后端拼HTML字符串,比较高级一点的想法是后端提前准备一些静态模板,通过在后端替换模块参数来实现,最终返回替换后的HTML。对于前后端分离的开发方式来说,客户端渲染肯定是主要方式。
前端本质上就是面向浏览器编程,这也是为人诟病前端深度不够的原因之一吧?浏览器在前端的地位类似操作系统之于后端,所以我认为后端是面向操作系统编程(如今也可能是面向云平台编程)。HTML CSS JS感悟到的大体就是这些,下面继续谈谈在这段时间对前端框架React的理解。
前端框架 React
React做了什么
前端框架主要流行的是Agular,Vue,React,学习了一点React,也做一些总结。React就是一个JS的库,跟java中的三方开源jar包、linux的基本工具没有什么区别,都是别人写好的工具,目的是提高软件复用性,免得自己重新造轮子,直接使用这些库会让编程更简单。那么,它是怎么让前端编程更简单的呢:核心思想就是封装浏览器的DOM对象的操作API,所以推想一下,所有的前端框架核心要义肯定都是干的这个事。
React核心库
React的核心API封装在两个库里,分别为react和react-dom,react负责操作虚拟DOM对象,我虽然没看过react的代码,但也能推想出虚拟DOM对象跟实际的浏览器DOM对象之间必然存在某种映射关系,react库操作虚拟DOM对象并不会导致浏览器的界面发生任何变化,react-dom库则负责将虚拟DOM对象中的操作迁移到真实浏览器的DOM对象中,最终导致浏览器的界面进行重绘,框架针对DOM对象操作可以有自己的优化(让DOM对象的操作更加高效)。将虚拟DOM对象操作和浏览器的DOM对象操作划分到react和react-dom两个模块中,非常符合面向对象设计原则,职责单一,提高了模块的复用性,也可以保证在修改react库时尽可能避免影响到react-dom,另外将react-dom分离出去,可以支持更多不同浏览器甚至是不同设备的渲染,非常好的设计:本质就是视图结构与视图渲染的分离。
React的概念
React具有一些比较高级点的概念。
组件和组件生命周期
组件体现了面向对象封装的概念,让代码可以更好的复用,生命周期的概念跟spring中的bean生命周期类似,就是初始化前干什么,初始化后干什么等等,本质上是React的组件对外提供的一些回调函数,React会在固定时机对这些回调函数进行调用,满足用户使用需求。
state和props
state和props是React中给组件提供数据的方式,state存储变化的状态,props作为不可变数据向子组件进行参数传递。props传递数据是自顶向下传送的,跟瀑布一样,那么,下层组件如何将状态的变动反馈给上层组件呢?这时候就需要使用state属性,React的具体做法是父组件通过将setState方法或者封装了setState方法的函数作为回调函数传递到子组件中,由子组件在状态变化时调用回调函数,进而触发了setState方法,setState方法的调用会导致React重新渲染浏览器,这样就做到了自底向上传递状态的目的。本质嘛,其实就是个setState作为回调函数,当做参数从父组件传入子组件,这块没有多么复杂的概念。
redux
redux是对flux模式的具体实现,flux的核心思想是action,store两个模块,state集中存储在store中,使得每个组件中无需维护state,在大型项目中就不需要再为修改一个小点而到处寻找维护该state的相关组件。store拥有dispatch方法和subscribe方法,dispatch方法接受的参数类型为action,action中包含action的类型以及action所携带的数据,action实例在传入store的dispatch方法后,会在store内部修改state,store通过subscribe方法注册渲染动作的回调函数,在store修改完state后,触发之前subscribe方法中注册的回调函数完成浏览器的重新渲染。
redux实现使用起来非常简便,这种模式也同样符合面向对象设计原则,虽然架构上添加了一层,但是做到了解耦,state集中存储,所以无需再关心state存储在哪里,关于state的逻辑添加与修改也就更加集中,受影响模块就更少。使用方式可以直接通过组件显示地传递store、通过上下文传递store、或者使用react-redux的Provider和connect函数来传递store(削减了处理store实例的工作量)。
React测试
Jest和Enzyme,非常不错的测试工具,支持mock、快照测试、覆盖率统计。
复盘结束
没错,到这就没了。
网友评论