上年在知乎听的第一场live,也算是为知识付费捐了点入场费,前端圈好像崇拜风气还是有的,因为我就是这样的人,哈哈,我觉得可以这样想,尤大是个人开发者,技术不用说,能开发出完整的前端框架,在营销,设计,拓宽影响力方面也是一流,大概这就是受欢迎的原因吧,每个开发者心中大概都有一个梦,创造出自己的作品。不可否认vue的火和代码思想,设计,作者个人魅力,群众的需求共同紧密相连,下面是上一年看完后写的记录,搬到此处,live只能听懂前半部分,手动狗头,当然作者也说了,每个部分拿出来都可以讲几节课的,注:总体按照大纲进行,中间穿插作者引申的概念等
组件的理解和分类
主流框架已经把组件作为最基本的抽象单元,最早前端开发以页面为抽象单位,但由于复杂度的上升,页面逐渐变为了应用,应用就有模块封装切分的需求,很快我们发现应用可以抽象为组件树。
React在该领域最大贡献是揭示了一个事实,组件可以是函数,一个组件可以调用其他函数,构成了一个树状结构。但是简单函数在实际应用中是不够的,所以 React 默认组件形式还是有 state ,用类似 class 的形式去包装。
组件的状态(state)
一个组件可以有多种形态,比如上面的柱状组件可以是硬直状态,也可以是疲软状态。(原谅我飙车了)。
四种类型的组件
展示型 单纯的显示 View。
接入型 即 container component,主要和数据层的 service 打交道。
交互型 比如各类加强版的表单组件,通常强调复用。
功能型 比如 ,,作为一种扩展、抽象机制存在。
模板和JSX的对比
JSX:本质上就是 js,具有 js 的灵活性,在书写功能型组件是远超模板的。
模板:写纯展示型更方便,强制分离交互逻辑,只做纯展示。
JSX 适合逻辑多的场景,模板适合逻辑少的场景。
Colocation
把该放在一起的东西放在一起。
跟几年前的 HTML、CSS、JS 分离对应。
Separation of Concerns
关注点分离
前端的关注点分离就是 HTML、CSS、JS 分离。
现在前端框架渲染最重要的就是声明式(Declarative)。相比较的就是命令式(Imperative),命令式最直接的例子 jQuery 代码,写到最后因为不直观很难维护。但声明式渲染方式好处是直接描述 DOM 和数据的结构关系是怎样的,一目了然。
Declarative Programming 声明式编程
你说有啥,就有啥。
Imperative Programming 命令式编程
你让我干啥,我就干啥。
意大利面条式编程
你觉得谁的代码烂,你就可以说谁的代码是意大利面条。Spaghetti code
view = render(state)
给我一个 state(数据),我就造出一个 view(DOM)。
熟悉 React 框架的都熟悉这个等式,view 的模版由输入的 state 渲染(render) 生成,底层实现可以是 virtual dom,但不是唯一选择,也可以使用细粒度的绑定(如 VUE),本质上是一样的,区别是在不同场景下更新效率的区别。
Change detection 变化侦测
监听一个对象,当对象变化时,你可以做一些事情。
Pure Component
一个 Pure Component 就是一个无副作用的函数。(React Components)
onclick="clickHandler" 的问题
clickHandler 是全局变量,这很烦人。
全局变量借祸害。
变化侦测机制
使用 VUE 的开发者都知道 VUE 的数据是响应式的,VUE 会把交给它的数据进行转化后展示,转化完成之后当你改变属性值(mutate)VUE 也会做出相应更新(Reactivity in Frontend JavaScript Frameworks)。
变化侦测主要分为两种 push 和 pull。
pull
React 的 setState 和 Angular 的脏检查都属于 pull,系统不知什么时候变,有可能变了,他需要一个信号,暴力的比对查出哪些变了,可以这样做的原因呢 ,就是js快了,虽然尤浪费,但可接受框架需要一个信号告知数据有改变,系统才会作出一个 diff,在 React 中是 dom diff,在 Angular 中是脏检查,能够这样做是现在 Javascript 足够快,虽然性能有浪费,但是整体还是可以接受。
push
VUE1 或 RxJS,数据变了之后可以立即知道哪些数据变动,可以进行更细粒度的更新,但是这也有代价,每一个绑定都会有一个 observerable 的 watcher,会带来内存开销。
VUE2 采用中等粒度的方案,在组件级别是 push,每一个组件是一个响应式的 watcher,当数据变动之后可以直接知道哪些组件变了,组件可以进行更新,在组件内部使用 virtual dom 进行比对。vue相当于采用混合式的
push 和 pull 之间本质区别是用侦测成本换取一定程度的自动优化。
路由
路由就是映射。给路由一个 url,路由就可以还你一个页面
路由是 SPA 时期遇到的问题,Angular2 是采用路径映射到组件的形式,React Router 和 VUE Router 也是采用组件映射路由的方式。
最简单的路由是一个动态组件,但是需要实现的时候路由会有很多问题:hash 模式和 history 模式如何兼容和 fallback;重定向;别名;懒加载;最复杂的是跳转,跳转需要提供钩子,钩子里面会使用异步操作,异步操作还有取消等一系列问题。
主流的路由方案比较相似,变化比较大的是 React Router 4,推崇的是使用组件本身来做路由的思路,很大程度利用之前说的第四类组件(功能型组件),可以在父组件中使用抽象的 Router 组件来声明式的渲染其他组件,和其他传统路由方案他是去中心化的,传统的是将路由表写在一个地方,React Router 4 是把路由分散的写在各个组件中。好处是灵活性非常高,但是路由结构不方便维护。
WEB 路由和 APP 路由的区别
WEB 路由是把路由映射到组件树,新的 URL push 到历史的 stack 中,stack 前一个界面的状态其实是丢弃掉的,但原生应用路由模式(Navigation)是类似与一叠卡片的状态,跳转触发后,新的界面是盖在之前的界面上,一层一层叠加的,退回去的时候是把当前的卡片拿掉,之前的卡片会出现。ionic 的路由方案是类是原生应用那种的,但 ionic 的方案不够声明式。
状态和数据流管理
总得来说前端对状态管理还没有达成共识,但又没有特别大的分歧。
可以了解一下 Flux、Redux、MobX、Vuex 和 Rx.js(反正名字里都有一个 x)。
状态管理主要涉及 event、state 和 view 的变化的管理,主要分歧在于 event 与 state 变化的管理方式,各种方案皆有优劣。
状态管理的始祖是 flux,flux 在初期的混战方案形成了 redux 和 MobX,VUEX 其实受 redux 影响比较多。
状态管理的本质是从源事件(source event)映射到状态的改变,然后在映射到 UI 的变化。
redux 和 MobX 提现了两种不同的范式(paradigm),redux 强调的是数据不可变,reducer 是一个纯函数,拿到原来的 state 和 action,返回的是一个新的 state。MobX 的数据可变,数据本身是响应式的,当数据发生改变通过之前的定义的观察器做出操作。
可把 Vue 当 redux 用把 Vue 当 MobX 用
redux 和 MobX 两者很相似,也有相同的问题,都没有对异步做出较好的支持,redux 是把异步交给 middleware,MobX 和 VUE 是让用户在 action 中进行操作。因为 redux 的 middleware 众多,所以各自基于 redux 的 middleware 形成了各个不同的方案,对简单的 CRUD 应用没有必要采用如此复杂方案,对应复杂请求(推送,实时更新)推荐使用 RxJS 做一层封装。
RxJS 使用流的方式直接从事件源映射到我们想要的结果。
数据抓取和同步
CSS 管理方案
现行的主流的 CSS 方案:
跟 JS 完全解耦,靠预处理器和比如 BEM 这样的规范来保持可维护性,偏传统。一种 CSS 命名方式,很容易被新手玩坏(不遵守规则)
CSS Modules,依然是 CSS,但是通过编译来避免 CSS 类名的全局冲突。新手也玩不坏。
各类 CSS-in-JS 方案,React 社区为代表,比较激进。不写 CSS,写 JS,已经有几十种方案了,选择恐惧症的死讯。
Vue 的单文件组件 CSS,或是 Angular 的组件 CSS(写在装饰器里面),一种比较折中的方案。
在比较这几种 CSS 方案时要明确场景的问题,在传统静态界面使用传统的 CSS 方案没什么问题,但是在组件化,单页应用的场景下传统的 CSS 书写方式会有维护的问题,使用 BEM 其实是维护和组件平行的命名方式,思维负担比较重。
传统 css 的一些问题
作用域
组件对应的 CSS 不希望污染全局,CSS Modules 和 inline styles 等可以解决。
Critical CSS 关键 CSS
首屏 CSS 所需 CSS 不需要其他页面的 CSS,CSS-in-JS 解决该方案比较好。
Atomic CSS
尽可能把 CSS 规则压缩的更小,使用原子类。
分发复用
CSS-in-JS 可以发包到 NPM 复用,因为全部是 Javascript,但是现在 webpack 可以做到这一点,不必要 CSS-in-JS。
跨平台复用
也可以将 CSS 编译为 Javascript 可以复用。
构建工具链
大神张云龙的博客,关于前端工程化
任务的自动化
开发体验和效率(新的语言功能,语法糖,hot reload 等等)
部署相关的需求
编译时优化
构建工具日新月异,前端的能力越来越强,WEB 的需求也越来越复杂,对前端的要求也越来越高,面对复杂度不同的需求,需要的工具也不同。
构建工具 任务自动化 语法糖 编译和优化 热加载 构建 js有babel 部署优化 配置的时候付出很多代价,但是收益也很大的,webpack大,就是因为他解决的问题就很困难
grunt 和 gulp 在绝大多数情况下可以使用 npm script 替代,所以用的人比较少。
Rollup 在打包效率和 tree shaking 方面做的比 webpack 好,React 也采用 Rollup 打包。
同构/服务端渲染
vue SSR指南
跨平台渲染
跨平台渲染的本质是在设计框架的时候要让框架的渲染机制和 DOM 解耦,也有多种实现形式,并不一定需要 virtual dom,virtual dom 是一个比较简单的途径。只要把框架更新时的节点操作封装起来就可以做到跨平台了,换言之就是原生的渲染引擎,像 React Native 和 Weex 底层都是针对不同的平台有适配的渲染引擎,只要把渲染引擎暴露的API和运行时对接,就可以实现框架代码渲染到原生 APP 的目的。
类型系统
构建时优化
运行时优化
Web Components 和框架的关系
Web Component 和类 React、Angular、Vue 组件化技术谁会成为未来?
Web Assembly 和框架的关系
web assembly 是跑在浏览器中的汇编语言,可以对接其他语言,但现在不太成熟。
上年在知乎听的第一场live,也算是为知识付费捐了点入场费,前端圈好像崇拜风气还是有的,因为我就是这样的人,哈哈,我觉得可以这样想,尤大是个人开发者,技术不用说,能开发出完整的前端框架,在营销,设计,拓宽影响力方面也是一流,大概这就是受欢迎的原因吧,每个开发者心中大概都有一个梦,创造出自己的作品。不可否认vue的火和代码思想,设计,作者个人魅力,群众的需求共同紧密相连,下面是上一年看完后写的记录,搬到此处,live只能听懂前半部分,手动狗头,当然作者也说了,每个部分拿出来都可以讲几节课的,注:总体按照大纲进行,中间穿插作者引申的概念等
组件的理解和分类
主流框架已经把组件作为最基本的抽象单元,最早前端开发以页面为抽象单位,但由于复杂度的上升,页面逐渐变为了应用,应用就有模块封装切分的需求,很快我们发现应用可以抽象为组件树。
React在该领域最大贡献是揭示了一个事实,组件可以是函数,一个组件可以调用其他函数,构成了一个树状结构。但是简单函数在实际应用中是不够的,所以 React 默认组件形式还是有 state ,用类似 class 的形式去包装。
组件的状态(state)
一个组件可以有多种形态,比如上面的柱状组件可以是硬直状态,也可以是疲软状态。(原谅我飙车了)。
四种类型的组件
展示型 单纯的显示 View。
接入型 即 container component,主要和数据层的 service 打交道。
交互型 比如各类加强版的表单组件,通常强调复用。
功能型 比如 ,,作为一种扩展、抽象机制存在。
模板和JSX的对比
JSX:本质上就是 js,具有 js 的灵活性,在书写功能型组件是远超模板的。
模板:写纯展示型更方便,强制分离交互逻辑,只做纯展示。
JSX 适合逻辑多的场景,模板适合逻辑少的场景。
Colocation
把该放在一起的东西放在一起。
跟几年前的 HTML、CSS、JS 分离对应。
Separation of Concerns
关注点分离
前端的关注点分离就是 HTML、CSS、JS 分离。
现在前端框架渲染最重要的就是声明式(Declarative)。相比较的就是命令式(Imperative),命令式最直接的例子 jQuery 代码,写到最后因为不直观很难维护。但声明式渲染方式好处是直接描述 DOM 和数据的结构关系是怎样的,一目了然。
Declarative Programming 声明式编程
你说有啥,就有啥。
Imperative Programming 命令式编程
你让我干啥,我就干啥。
意大利面条式编程
你觉得谁的代码烂,你就可以说谁的代码是意大利面条。Spaghetti code
view = render(state)
给我一个 state(数据),我就造出一个 view(DOM)。
熟悉 React 框架的都熟悉这个等式,view 的模版由输入的 state 渲染(render) 生成,底层实现可以是 virtual dom,但不是唯一选择,也可以使用细粒度的绑定(如 VUE),本质上是一样的,区别是在不同场景下更新效率的区别。
Change detection 变化侦测
监听一个对象,当对象变化时,你可以做一些事情。
Pure Component
一个 Pure Component 就是一个无副作用的函数。(React Components)
onclick="clickHandler" 的问题
clickHandler 是全局变量,这很烦人。
全局变量借祸害。
变化侦测机制
使用 VUE 的开发者都知道 VUE 的数据是响应式的,VUE 会把交给它的数据进行转化后展示,转化完成之后当你改变属性值(mutate)VUE 也会做出相应更新(Reactivity in Frontend JavaScript Frameworks)。
变化侦测主要分为两种 push 和 pull。
pull
React 的 setState 和 Angular 的脏检查都属于 pull,系统不知什么时候变,有可能变了,他需要一个信号,暴力的比对查出哪些变了,可以这样做的原因呢 ,就是js快了,虽然尤浪费,但可接受框架需要一个信号告知数据有改变,系统才会作出一个 diff,在 React 中是 dom diff,在 Angular 中是脏检查,能够这样做是现在 Javascript 足够快,虽然性能有浪费,但是整体还是可以接受。
push
VUE1 或 RxJS,数据变了之后可以立即知道哪些数据变动,可以进行更细粒度的更新,但是这也有代价,每一个绑定都会有一个 observerable 的 watcher,会带来内存开销。
VUE2 采用中等粒度的方案,在组件级别是 push,每一个组件是一个响应式的 watcher,当数据变动之后可以直接知道哪些组件变了,组件可以进行更新,在组件内部使用 virtual dom 进行比对。vue相当于采用混合式的
push 和 pull 之间本质区别是用侦测成本换取一定程度的自动优化。
路由
路由就是映射。给路由一个 url,路由就可以还你一个页面
路由是 SPA 时期遇到的问题,Angular2 是采用路径映射到组件的形式,React Router 和 VUE Router 也是采用组件映射路由的方式。
最简单的路由是一个动态组件,但是需要实现的时候路由会有很多问题:hash 模式和 history 模式如何兼容和 fallback;重定向;别名;懒加载;最复杂的是跳转,跳转需要提供钩子,钩子里面会使用异步操作,异步操作还有取消等一系列问题。
主流的路由方案比较相似,变化比较大的是 React Router 4,推崇的是使用组件本身来做路由的思路,很大程度利用之前说的第四类组件(功能型组件),可以在父组件中使用抽象的 Router 组件来声明式的渲染其他组件,和其他传统路由方案他是去中心化的,传统的是将路由表写在一个地方,React Router 4 是把路由分散的写在各个组件中。好处是灵活性非常高,但是路由结构不方便维护。
WEB 路由和 APP 路由的区别
WEB 路由是把路由映射到组件树,新的 URL push 到历史的 stack 中,stack 前一个界面的状态其实是丢弃掉的,但原生应用路由模式(Navigation)是类似与一叠卡片的状态,跳转触发后,新的界面是盖在之前的界面上,一层一层叠加的,退回去的时候是把当前的卡片拿掉,之前的卡片会出现。ionic 的路由方案是类是原生应用那种的,但 ionic 的方案不够声明式。
状态和数据流管理
总得来说前端对状态管理还没有达成共识,但又没有特别大的分歧。
可以了解一下 Flux、Redux、MobX、Vuex 和 Rx.js(反正名字里都有一个 x)。
状态管理主要涉及 event、state 和 view 的变化的管理,主要分歧在于 event 与 state 变化的管理方式,各种方案皆有优劣。
状态管理的始祖是 flux,flux 在初期的混战方案形成了 redux 和 MobX,VUEX 其实受 redux 影响比较多。
状态管理的本质是从源事件(source event)映射到状态的改变,然后在映射到 UI 的变化。
redux 和 MobX 提现了两种不同的范式(paradigm),redux 强调的是数据不可变,reducer 是一个纯函数,拿到原来的 state 和 action,返回的是一个新的 state。MobX 的数据可变,数据本身是响应式的,当数据发生改变通过之前的定义的观察器做出操作。
可把 Vue 当 redux 用把 Vue 当 MobX 用
redux 和 MobX 两者很相似,也有相同的问题,都没有对异步做出较好的支持,redux 是把异步交给 middleware,MobX 和 VUE 是让用户在 action 中进行操作。因为 redux 的 middleware 众多,所以各自基于 redux 的 middleware 形成了各个不同的方案,对简单的 CRUD 应用没有必要采用如此复杂方案,对应复杂请求(推送,实时更新)推荐使用 RxJS 做一层封装。
RxJS 使用流的方式直接从事件源映射到我们想要的结果。
数据抓取和同步
CSS 管理方案
现行的主流的 CSS 方案:
跟 JS 完全解耦,靠预处理器和比如 BEM 这样的规范来保持可维护性,偏传统。一种 CSS 命名方式,很容易被新手玩坏(不遵守规则)
CSS Modules,依然是 CSS,但是通过编译来避免 CSS 类名的全局冲突。新手也玩不坏。
各类 CSS-in-JS 方案,React 社区为代表,比较激进。不写 CSS,写 JS,已经有几十种方案了,选择恐惧症的死讯。
Vue 的单文件组件 CSS,或是 Angular 的组件 CSS(写在装饰器里面),一种比较折中的方案。
在比较这几种 CSS 方案时要明确场景的问题,在传统静态界面使用传统的 CSS 方案没什么问题,但是在组件化,单页应用的场景下传统的 CSS 书写方式会有维护的问题,使用 BEM 其实是维护和组件平行的命名方式,思维负担比较重。
传统 css 的一些问题
作用域
组件对应的 CSS 不希望污染全局,CSS Modules 和 inline styles 等可以解决。
Critical CSS 关键 CSS
首屏 CSS 所需 CSS 不需要其他页面的 CSS,CSS-in-JS 解决该方案比较好。
Atomic CSS
尽可能把 CSS 规则压缩的更小,使用原子类。
分发复用
CSS-in-JS 可以发包到 NPM 复用,因为全部是 Javascript,但是现在 webpack 可以做到这一点,不必要 CSS-in-JS。
跨平台复用
也可以将 CSS 编译为 Javascript 可以复用。
构建工具链
大神张云龙的博客,关于前端工程化
任务的自动化
开发体验和效率(新的语言功能,语法糖,hot reload 等等)
部署相关的需求
编译时优化
构建工具日新月异,前端的能力越来越强,WEB 的需求也越来越复杂,对前端的要求也越来越高,面对复杂度不同的需求,需要的工具也不同。
构建工具 任务自动化 语法糖 编译和优化 热加载 构建 js有babel 部署优化 配置的时候付出很多代价,但是收益也很大的,webpack大,就是因为他解决的问题就很困难
grunt 和 gulp 在绝大多数情况下可以使用 npm script 替代,所以用的人比较少。
Rollup 在打包效率和 tree shaking 方面做的比 webpack 好,React 也采用 Rollup 打包。
同构/服务端渲染
vue SSR指南
跨平台渲染
跨平台渲染的本质是在设计框架的时候要让框架的渲染机制和 DOM 解耦,也有多种实现形式,并不一定需要 virtual dom,virtual dom 是一个比较简单的途径。只要把框架更新时的节点操作封装起来就可以做到跨平台了,换言之就是原生的渲染引擎,像 React Native 和 Weex 底层都是针对不同的平台有适配的渲染引擎,只要把渲染引擎暴露的API和运行时对接,就可以实现框架代码渲染到原生 APP 的目的。
类型系统
构建时优化
运行时优化
Web Components 和框架的关系
Web Component 和类 React、Angular、Vue 组件化技术谁会成为未来?
Web Assembly 和框架的关系
web assembly 是跑在浏览器中的汇编语言,可以对接其他语言,但现在不太成熟。