ziwei3749 / blog

已停止更新..转移至 https://segmentfault.com/u/ziwei3749

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

不黑不吹聊聊前端框架

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,跟底层渲染引擎解耦就行。