六、框架和类库
TypeScript
-
理解泛型、接口等面向对象的相关概念,TypeScript对面向对象理念的实现
泛型:
工程中,我们不仅要创建一致的定义良好的API也要考虑重用性。组件不仅能支持未来的数据类型,也能支持未来的数据类型。
泛型就是用来创建可重用的组件,一个组件可以支持多种类型的数据。
function getData<T>(value: T):T{
return value;
}
getData<number>(123);
getData<string>('21231');
接口:
在TypeScript里,接口的作用就是为这些类型命名和为代码定义契约。
TypeScript就是一个基于类的面向对象编程语言。类的继承,重写。接口,泛型,命名空间
-
理解使用TypeScript的好处,掌握TypeScript基础语法
typescript提供了一套强类型的规范。便于模块管理,团队协作,开发严谨且自由。静态类型检查,IDE只能提示,代码重构可读性高。
-
TypeScript的规则检测原理
-
可以在React、Vue等框架中使用TypeScript进行开发
React
-
React和vue选型和优缺点、核心架构的区别
主要区别:
1.模板 vs JSX
2.状态管理 vs 对象属性
-
React中setState的执行机制,如何有效的管理状态
特点:
setState是同步执行的,但state不一定会同步更新;
setState在React生命周期合成事件中批量覆盖执行
setState在原生事件,setTimeout、Promise等异步操作中,state会同步更新
基本过程:setState的调用会引起React的更新生命周期的4个函数执行。
shouldComponentUpdate
componentWillUpdate
render
componentDidUpdate
当shouldComponentUpdate执行时,返回true,进行下一步,this.state没有被更新
返回false,停止,更新this.state
当componentWillUpdate被调用时,this.state也没有被更新
直到render被调用时候,this.state才被更新
因为组件中的某些属性是和视图没有关系的,当组件变得复杂的时候可能会出现各种各样的状态需要管理,这时候用setState管理所有状态是不可取的。state中本应该只保存与渲染有关的状态,而与渲染无关的状态尽量不放在state中管理,可以直接保存为组件实例的属性,这样在属性改变的时候,不会触发渲染,避免浪费
-
React的事件底层实现机制
事件合成:形成namesToPlugins、registrationNameModules等几个重要对象,构建初始化React合成事件和对应的事件处理插件关系
事件绑定:根据合成事件类型,找到对应原生事件的类型,调用 addTrappedEventListener 进行真正的事件绑定,绑定在document
上(react17绑定在container上),dispatchEvent
为统一的事件处理函数
事件触发:通过统一的事件处理函数 dispatchEvent
,进行批量更新batchUpdate。
-
React的虚拟DOM和Diff算法的内部实现
React
会先将你的代码转换成一个JavaScript
对象,然后这个JavaScript
对象再转换成真实DOM
。这个JavaScript
对象就是所谓的虚拟DOM
。
-
React的Fiber工作原理,解决了什么问题
有react fiber,为什么不需要vue fiber呢?
-
React Router 和 Vue Router的底层实现原理、动态加载实现原理
-
可熟练应用React API、声明周期等,可应用HOC、render props、Hooks等高阶用法解决问题
Mixin的缺陷:
-
组件与 Mixin 之间存在隐式依赖(Mixin 经常依赖组件的特定方法,但在定义组件时并不知道这种依赖关系)
-
多个 Mixin 之间可能产生冲突(比如定义了相同的state字段)
-
Mixin 倾向于增加更多状态,这降低了应用的可预测性(The more state in your application, the harder it is to reason about it.),导致复杂度剧增
-
隐式依赖导致依赖关系不透明,维护成本和理解成本迅速攀升:
-
难以快速理解组件行为,需要全盘了解所有依赖 Mixin 的扩展行为,及其之间的相互影响
-
组价自身的方法和state字段不敢轻易删改,因为难以确定有没有 Mixin 依赖它
-
Mixin 也难以维护,因为 Mixin 逻辑最后会被打平合并到一起,很难搞清楚一个 Mixin 的输入输出
-
HOC相比Mixin的优势:
- HOC通过外层组件通过 Props 影响内层组件的状态,而不是直接改变其 State不存在冲突和互相干扰,这就降低了耦合度
- 不同于 Mixin 的打平+合并,HOC 具有天然的层级结构(组件树结构),这又降低了复杂度
HOC的缺陷:
- 扩展性限制: HOC 无法从外部访问子组件的 State因此无法通过shouldComponentUpdate滤掉不必要的更新,React 在支持 ES6 Class 之后提供了React.PureComponent来解决这个问题
- Ref 传递问题: Ref 被隔断,后来的React.forwardRef 来解决这个问题
- Wrapper Hell: HOC可能出现多层包裹组件的情况,多层抽象同样增加了复杂度和理解成本
- 命名冲突: 如果高阶组件多次嵌套,没有使用命名空间的话会产生冲突,然后覆盖老属性
- 不可见性: HOC相当于在原有组件外层再包装一个组件,你压根不知道外层的包装是啥,对于你是黑盒
Render Props优点:
- 上述HOC的缺点Render Props都可以解决
Render Props缺陷:
- 使用繁琐: HOC使用只需要借助装饰器语法通常一行代码就可以进行复用,Render Props无法做到如此简单
- 嵌套过深: Render Props虽然摆脱了组件多层嵌套的问题,但是转化为了函数回调的嵌套
React Hooks优点:
- 简洁: React Hooks解决了HOC和Render Props的嵌套问题,更加简洁
- 解耦: React Hooks可以更方便地把 UI 和状态分离,做到更彻底的解耦
- 组合: Hooks 中可以引用另外的 Hooks形成新的Hooks,组合变化万千
- 函数友好: React Hooks为函数组件而生,从而解决了类组件的几大问题:
- this 指向容易错误
- 分割在不同声明周期中的逻辑使得代码难以理解和维护
- 代码复用成本高(高阶组件容易使代码量剧增)
React Hooks缺陷:
-
额外的学习成本(Functional Component 与 Class Component 之间的困惑)
-
写法上有限制(不能出现在条件、循环中),并且写法限制增加了重构成本
-
破坏了PureComponent、React.memo浅比较的性能优化效果(为了取最新的props和state,每次render()都要重新创建事件处函数)
-
在闭包场景可能会引用到旧的state、props值
-
内部实现上不直观(依赖一份可变的全局状态,不再那么“纯”)
-
React.memo并不能完全替代shouldComponentUpdate(因为拿不到 state change,只针对 props change)
-
基于React的特性和原理,可以手动实现一个简单的React
Vue
-
熟练使用Vue的API、生命周期、钩子函数
-
MVVM框架设计理念
-
Vue双向绑定实现原理、Diff算法内部实现
双向绑定原理:Vue内部通过Object.defineProperty方法属性拦截的方式,把data对象里每个数据的读写转化成getter/setter,当数据变化时通知视图更新。
Diff算法:修改dom时只修改一小块,不更新整个dom进行整个dom树的重绘。根据真实DOM生成一个vietual DOM。
-
Vue的事件机制
Vue定义了四种事件监听的API:$on、$once、$off、$emit
-
从template转换成真实DOM的实现机制
template => DOM在Vue构建过程中的$mount过程开始的,template先是被编译成render function,再被渲染成真实DOM。被编译的过程:
第一步,parse解析成ast树
第二步,对ast树进行optimize,检测出其中不需要进行改变的DOM静态子树(可在后续渲染真实DOM过程中petch跳过,减少使用diff算法的工作量)
最后,generate成所需的code,将ast语法树转化成render function字符串。
从template到DOM(Vue.js源码角度看内部运行机制)
多端开发
-
单页面应用SPA的原理和优缺点,掌握一种快速开发SPA的方案
单页面Web应用(single-page application,SPA):
仅在web页面初始化时加载相应的HTML、JS、CSS,一旦页面加载完成了,SPA不会因为用户的操作而进行页面的重新加载或跳转,而是利用JS动态的变换HTML,从而实现UI与用户的交互。
优缺点:
1、优点:避免了页面的重新加载,SPA可以提供较为流畅的用户体验,实现无跳转刷新。由于浏览器的history机制,用hash的变化从而推动页面变化。
2、缺点:以SPA方式开发的网站不容易管理也不够安全。由于没有一页一页的网页给搜索引擎的爬虫去爬,所以在搜索引擎最佳化SEO的工作上需花费额外功夫。
-
理解viewport、em、rem的原理和用法,分辨率、px、ppi、dpi、dp的区别和实际应用
viewport就是视区窗口,也就是浏览器中显示网页的部分。PC 端上基本等于设备显示区域,但在移动端上 viewport
会超出设备的显示区域(即会有横向滚动条出现)。
设备默认的viewport在980 - 1024 之间。viewport 实在 meta标签内进行控制
设置 | 解释 |
width | 设置layout viewport的宽度,为一个正整数或字符串“width-device” |
initial-scale | 设置页面的初始缩放值,为一个数字,可以带小数 |
minimum-scale | 允许用户的最小缩放值,为一个数字,可以带小数 |
maximum-scale | 允许用户的最大缩放值,为一个数字,可以带小数 |
height | 设置 layout viewport 的高度,这个属性对我们并不重要,很少使用 |
user-scalable | 是否允许用户进行缩放,值为"no"或"yes", no 代表不允许,yes 代表允许 |
默认情况下: 1em = 10px; 1rem = 16px
px: 绝对固定的值,无论页面放大或者缩小都不会改变。
em: 相对父元素字体大小的倍数。如果父元素的字体为 12px
,那么子元素 1em
就是 24px
。由于是相对父级的倍数,所以多层嵌套时,倍数关系的计算会很头痛。
rem: 相对根元素字体大小的倍数。相对于 html
的字体大小,如果不做任何修改,浏览器默认字体大小为 16px
。
ppi:每英寸像素数,该值越高,则屏幕越细腻
dpi:每英寸多少个点,该值越高,则图片越细腻
dp:安卓开发用的长度,1dp表示在屏幕像素点密度为160ppi时1px长度
-
移动端页面适配解决方案、不同机型适配方案
1、固定高度,宽度自适应。水平方向使用弹性布局,元素采用定值、百分比、flex布局等
2、固定布局视口宽度,使用viewport进行缩放
3、根据不同屏幕动态写入font-size,以rem作为宽度单位,固定布局视口
4、以rem作为宽度单位,动态写入viewport和font-size进行缩放
5、根据不同屏幕动态写入font-size和viewport,以热门作为宽度单位
-
掌握一种JS PC客户端开发技术,如Electron:可搭建Electron开发环境,熟练进行开发,可理解Electron的运作原理
Electron是又github开发,用HTML、CSS、JS来构建跨平台桌面应用程序的一个开源库。可以看作一个Node.js的变体。
Electron 结合了 Chromium、Node.js 和用于调用操作系统本地功能的API。
-
掌握一种小程序开发框架或原生小程序开发
-
理解多端框架的内部实现原理,至少了解一个多端框架的使用
数据流管理
-
掌握React和Vue传统的跨组件通讯方案,对比采用数据流管理框架的异同
-
熟练使用Redux管理数据流,并理解其实现原理,中间件实现原理
一篇文章总结redux、react-redux、redux-saga
-
熟练使用Mobx管理数据流,并理解其实现原理,相比Redux有什么优势
-
熟练使用Vuex管理数据流,并理解其实现原理
-
以上数据流方案的异同和优缺点,不同情况下技术选型
所以无论是技术栈还是框架。类库,并没有绝对的比较我们就应该选择什么,抛弃什么,我们应该更关注它们解决什么问题,它们解决问题的关注点,或者说实现方式是什么,它们的优缺点还有什么,哪一个更适合当前项目,以及项目未来发展
实用库
-
至少掌握一种UI框架,如antd design,理解其设计理念、底层实现
-
掌握一种图标绘制框架,如Echarts,理解其设计理念、底层实现,可以自己实现图表
ECharts使用的是ZRender底层渲染器。ZRender提供三种渲染器:Canvas、SVG和VML。它对上提供了一种渲染平台无关的图形接口,对下封装兼容不同平台的实现算法。
-
掌握一种GIS开发框架,如百度地图API
-
掌握一种可视化开发框架,如Three.js、D3
-
工具函数库,如lodash、underscore、moment等,理解使用工具类或工具函数的具体实现原理
开发和调试
-
熟练使用各浏览器提供的调试工具
Chrome浏览器调试器为例:前端chrome浏览器调试总结
-
熟练使用一种代理工具实现请求代理、抓包,如 charls
-
可以使用Android、IOS模拟器进行调试,并掌握一种真机调试方案
-
了解Vue、React等框架调试工具的使用