不黑不吹聊聊前端框架
ziwei3749 opened this issue · comments
不黑不吹聊聊前端框架
不黑不吹聊聊前端框架
- React最大的贡献,是揭示了一个事实,就是组件其实可以是一个函数。
一:组件的理解和分类
- 接入型 container
- 展示型
- 交互型 比如各类加强版的表单组件,通常强调复用
- 功能型 比如
<router-view>
,<transition>
,作为一种扩展、抽象机制存在。
关于模板和JSX的对比:
JSX最大的特点是灵活性,因为它具备JS这个语言的完全功能。
JSX最大的优点是在第四种,这个功能型组件上的强大是远超vue的模板的
但是vue模板呢,在展示型组件上写起来更爽,模板会强制性的让你把尽可能少的逻辑写在视图代码里。
关于组件化的Colocation
三大框架都是组件化的,都有会以一个组件为单位划分,把html.css.js该放到一起的放到一起
而以前流行的是,css js html文件
二: 变化侦测机制
Declarative Programming 声明式编程
Imperative Programming 命令式编程
React中: view = render(state)
Vue中.: .vue文件可以理解为跟jsx一样是一个语法糖。输入就是data,编译.vue文件就相当于执行了render,输出一个dom结构
自己写一个 Virtual DOM 库并不难。
vue里可以把click写在html上,和原生JS的区别,就是作用域的问题。原生的写出来作用域是全局的,很伤
变化侦测分2种:
- pull :
react里的setState,包括ng1里的脏检查。
就是系统其实不知道数据什么时候变了,它需要一个信号,就是数据什么时候有可能会发生变化?
一旦变化react里就会对虚拟dom做diff,ng里就是脏检查。所以这个是一个比较暴力的方式。
那能够这么做,是由于JS现在比较快,这么做性能上可以被接受。
- push:
vue里双向数据绑定或者RX.JS里observer的一些东西。
数据一旦变化,vue就可以知道哪些数据发生了变化,这样就可以做细粒度的更新。
所以react的diff算法这么暴力比对可能会做一些无用功,所以在react开发里会有一些性能优化技巧,在shouldUpdateComponent里
不过vue这种所谓细粒度的更新也有代价。就是这个每一个绑定都要有对应的oberverable和watcher,会有内存的开销和依赖追踪的开销。
所以在vue2.0之后,push和pull结合起来用,在组件级别是Push,我们可以准确的检测到哪个组件变了,在组件内部是virtual dom 来 比对更新
本质上: push的做法就是用侦测成本换取一定程度的自动优化。实际上也比较不出哪个好,哪个坏
三、状态管理
rx.js也和状态管理有一点关系
总得来说前端对状态管理还没有达成共识,但又没有特别大的分歧。
- redux : 数据不可变
- mobx : 数据可以变
- vuex
在现代web框架里,状态管理主要涉及event / state / view
event发生后,触发state的改变,state的变化触发view的变化。
而声明式渲染,其实vue /react已经做到了状态变化,对应视图就变化。
状态管理解决的主要是event到state变化的管理方案,如何把这个映射的部分抽离出来,更好的维护。
尤雨溪的看法呢:
redux本身是无法处理异步的,它是交给中间件来解决的。
react-thunk react-promise等方案,都很好用,但是写出来的代码差异有点大。
vuex觉得简单的项目不应该抽象太多层,如果真的项目复杂,也可以考虑增加rx.js来处理
这个可能是vuex/redux一点区别,但是他们也面临共同的一些问题:
缺乏划分全局状态和局部状态的标准和界限。
四、路由
只有在大型单页应用才会遇到的问题。最早的路由是比较有侵入性的,比如Ember.js
但是vue/react这种专注视图层的库出现后,其实把路由解耦出来是完全可行的。而且会发现从组件去思考,其实前端路由就是实现一个url映射到组件树结构的过程
这样考虑的话,就会觉得路由的实现,就像一个动态组件一个,url变化就切换组件。
看上去很容易,实际上路由会涉及到很多复杂情况:
- history和hash模式如何互相兼容
- 重定向 / 别名 / 懒加载
- 最复杂的是路由跳转需要提供各种钩子,这些钩子里开发者可能还需要做异步操作,还可能需要这次跳转,使得跳转无效
真正实现起来,还是有一些复杂度的。
目前router的实现方式比较相似,但react-router4的变化较大
-
推崇的是用组件本身去做路由的思路。之所以可以这么做,就是很好的利用了jsx对功能性组件的强大支持
-
跟前其他router实现的一个明显区别就是去中心化的。
- 好处是很灵活简洁。
- 但是也有问题:集中的路由表对理解整个项目的结构有帮助;
web路由和app路由的区别
- web路由回退会后,会丢失之前的状态。app应用就不会丢失
- 之后可能这个也是一个探索方向。
五、CSS方案
主流的 CSS 方案
- (传统做法)跟 JS 完全解耦,靠预处理器和比如 BEM 这样的规范来保持可维护性,偏传统
- CSS Modules,依然是 CSS,但是通过编译来避免 CSS 类名的全局冲突
- (比较激进)各类 CSS-in-JS 方案,React 社区为代表,比较激进
- (折中)Vue 的单文件组件 CSS,或是 Angular 的组件 CSS(写在装饰器里面),一种比较折中的方案
css in js可能是比较有争议的
六、构建工具
构建工具解决的其实是几方面的问题:
- 任务的自动化
- 开发体验和效率(新的语言功能,语法糖,hot reload 等等)
- 部署相关的需求
- 编译时优化
关于部署 https://www.zhihu.com/question/20790576
服务端渲染 ssr.vuejs.org
跨平台渲染
不一定用虚拟dom,跟底层渲染引擎解耦就行。