之前在明源云进行了电话面试,面试题大概如下:
Vue
vueRouter history模式与hash模式
hash
hash模式主要是根据window.onhashchange
事件函数监听url里hash值的变换来进行路由的跳转,而且服务器永远只会识别/#/
前面的部分,不需要在服务器配置所有的路由url
history
history模式没有/#/
号,是根据history
这个浏览器对象来实现路由的跳转,有go
、back
、forward
、pushState
、replaceState
等api,通过pushState
把页面的状态保存在state对象中,然后根监听window.onpopstate
事件函数来获取event.state
这个状态进行页面还原。但是由于histroy模式没有/#/
这个hash标识,就需要服务器直接所有的路由地址,否则当刷新某个路由地址时,去请求服务器,服务器找不到这个地址就会报404的错误。
Proxy解决了什么问题
- 解决了
object.definePropertiy
的无法监听到对象的添加与删除,需要调用Vue.set
方法进行添加,this.$delete
方法进行删除才能监听到响应式系统,还可以对整个data进行重新赋值 - 不能监听到数组的变化,现在可以是因为重新数组的一些方法
- 只能劫持到对象的属性,如果属性是对象还需要进行深度遍历
vue data为何要是function
因为组件复用会共享data
,如果data
是对象的话,一个组件修改data
那同时也会影响到另一个data
,现在组件使用了函数就解决这个问题,基于必包。
nextTick
意思就是在下次DOM更新循环结束之后执行回调,比如我需要在更新data
后需要获取真实的DOM的value,但此时是没有更新的,我们就可以使用nextTick
设置个回调函数即可。
React
React hook的特性
为什么要hook
- 使函数组件能够拥有状态
- 很难在组件之间服用状态逻辑(解决复用问题使得很多高阶组件嵌套、render prop导致的嵌套地狱)
- 复杂组件变得难以理解(hook可以把一些逻辑拆分为状态函数)
- class难以理解,需要去理解
this
的工作方式
React高阶组件 与 render propsx
高阶组件
本质是函数,接受组件作为参数,返回一个新的组件。主要是为了解决组件功能复用问题。有两种方式
- 属性代理:主要是继承React.Component,然后在
render
方法里引用传进来的组件。- 可以操作props
- 可以ref访问组件实例
- 操作state
- 组合html
- 反向继承:直接继承组件,render里也是返回该组件
- 操作state
- 渲染劫持,可以操作render
- 会丢失原本显示名
- 高阶组件的缺点
- 难以溯源,如果是由多个hoc组成的话,需要翻每个hoc知道各自的属性
- props属性名冲突,某个属性可能被多个hoc重复使用
- 静态构建,需要在页面构建前生成
Render Props
主要也是用于功能复用,本质就是给组件传入一个props
,然后在组件render里引用这个props
,有以下优点
- 数据单向流
- props不会有命名冲突
- 可以溯源
- 动态构建,可以在render里渲染
- 能完成所有hoc的功能
常用的必包
- 柯里化
- react的hook
- vue的component的data
- 计数器
- 避免污染全局环境
React生命周期
- constructor
- componentWillMount (pass)
- static getDerivedStateFromProps
- render
- componentDidMount
- shouldComponentUpdate
- componentWillUpdate(pass)
- componentWilReceiveProps(pass)
- static getSnapshotBeforeUpdate
- componentDidUpdate
- componentUnMount
左右定宽,中间自适应
绝对定位
左右两边布局设置绝对定位,中间的布局左右margin,缺点是脱离文档流。
flex
容器设置flex布局,中间布局flex等于1,缺点是无法直接优先加载中间布局,需要做别的处理,兼容性不是十分完美。
双飞翼
经典布局,兼容性好,中间内容优先加载。缺点是脱离文档流,需要清除浮动,中间布局额外DOM。
- 中间布局需要包裹一层content
- 左和content都需要设置左浮动,右布局设置右浮动
- content的width=100%,左边的margin-left=-100%,右边的margin-left=-右布局宽度
- 中间布局设置左右margin为左右布局宽度
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26<div class="container">
<div class="content">
<div class="main">main<div>
</div>
<div>left</div>
<div>right</div>
</div>
.left {
width: 300px;
display: inline-block;
float: left;
margin-left: -100%;
}
.right {
width: 300px;
float: right;
margin-left: -300px;
}
.container {
float: left;
width: 100%;
}
.main {
margin-left: 300px;
margin-right: 300px;
}
圣杯布局
也是经典布局,优点是不需要多余的DOM,其余和双飞翼一样
- 左和中间都需要设置左浮动,右布局设置右浮动
- main的width=100%,左边的margin-left=-100%,右边的margin-left=-右布局宽度
- 左右布局设置为相对布局,left=-300px;右布局right=-300px;
- 容器设置左右margin为300px
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29<div class="container">
<div class="main">main<div>
<div>left</div>
<div>right</div>
</div>
.left {
float: left;
width: 300px;
display: inline-block;
margin-left: -100%;
position: relative;
left: -300px;
}
.right {
float: right;
width: 300px;
display: inline-block;
margin-left: -300px;
position: relative;
right: -300px;
}
.main {
float: left;
width: 100%;
}
.container {
margin-left: 300px;
margin-right: 300px;
}
useCallback 与 useMemo
这两个hook函数的作用都是基于给定的依赖来进行缓存,而区别在于useCallback返回的是函数,而useMemo返回的是一个值。用法主要是在给子组件传递参数时,可以配合React.memo(作用是会对props做一个浅层比较,props没有修改的话,就不会渲染组件)来对子组件判断是否需要更新,从而节省不必要的更新。
diff的key值
key值可以在DOM中的某些元素被增加或者删除的时候帮助React识别哪些元素发生了变化。
- key值相同,组件有所变化,react会只更新组件对应变化的属性。
- key值不同,组件会摧毁之前的组件,讲整个组件重新渲染。
promise的all,race,allSettled
- all:promiseAll接收一组promise,只有这组promise全部状态变成fulfilled后,promiseAll状态才会变成fulfilled,此时返回值是一个数组,如果任意一个promise变成rejected,则promiseAll状态也会变成rejected,rejected返回值传给promiseAll
- race:参数与all的是一样,但是race只要任意一个promise状态变更后,promiseRace的状态也会跟着变,比如可以用来给promise设置超时时间。
- allSettled:只有所有的promise状态都变更后,包装实例才会结束,结束后状态总是fulfiled,参数是数组,如[{status: ‘fulfilled’, value: 43}]。
- any:只要任意一个变成fulfilled后,实例才会变成fulfilled,等所有实例变成rejected后,实例才会变成rejected。
bfc
bfc是一个独立的容器,有它自己的布局流
触发BFC
- body 根元素
- 浮动
- 绝对定位
- disaplay: inline-block、table-cells、flex
- overflow:hidden、auto、scroll
应用
- 解决BFC下外边距折叠
- 清除浮动
清除浮动
- 额外标签,添加标签加上属性clear: both;
- overflow: hidden,内容被隐藏
- after伪元素
1
2
3
4
5.container::after {
content: '';
clear: both;
display: block;
}
盒子模型
content-box
元素的宽度=width+padding+border+margin
border-box
元素的宽度=width,所有的padding、border、margin都包含在width里了
thunk与sega有啥不同
thunk
- 使用简单,直接dispatch一个函数
- action形式不统一
- action不易维护,每个异步都需要一个函数
- 操作分散,异步操作dispatch被分散在各个action中
sega
自己封装了一整套异步处理流程
- 使用了generator语法
- 集中处理所有异步操作
- action是普通对象
- 使用effect可以方便单元测试
- 异步操作流程可控制,随时取消
- 学习成本高
什么时候触发gpu加速
可以通过CSS属性
- translate3d
- translateZ
- rotate
- scale
webpack 懒加载
可以使用类似babel-plugin-syntax-dynamic-import这种预处理器,在使用时才去加载模块代码
若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏
扫描二维码,分享此文章