写在前面
五一过了代表新的一年不知不觉过了半年了,各位工作找到怎么样,有没有在工作中遇到解决不了的问题,这些问题后面怎么处理了呢?
hello大家好,我又又又来了,今天纯干货,上班的朋友适当摸鱼,不上班的找个舒服的姿势,再来包薯片,本文相关也可以【点击此处】
前端24年比23年更加难熬,从金三银四可以看出来,你敢跳一定是下了不少决心,那么有没有拿到想要的待遇呢,没有找到下家的现在还在找吗?
接下来给大家带来一篇复合式面试合集,也是希望浅浅的帮一下大家,加油哦!!!
目录展示
174页超长合集
174页超长合集
no.1 Vue中大厂常见面试题
说说vue动态权限绑定渲染列表(权限列表渲染)
1. 首先请求服务器,获取当前用户的权限数据,比如请求 this.$http.get("rights/list");
2. 获取到权限数据之后,在列表中使用v-if v-if-else的组合来展示不同的内容
<template>
<div>
<!-- 面包屑导航区 -->
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
<el-breadcrumb-item>权限管理</el-breadcrumb-item>
<el-breadcrumb-item>权限列表</el-breadcrumb-item>
</el-breadcrumb>
<!-- 卡片视图 -->
<el-card>
<el-table :data="rightsList" border stripe>
<el-table-column type="index" label="#"></el-table-column>
<el-table-column label="权限名称" prop="authName"></el-table-column>
<el-table-column label="路径" prop="path"></el-table-column>
<el-table-column label="权限等级" prop="level">
<template slot-scope="scope">
<el-tag v-if="scope.row.level === '0'">一级</el-tag>
<el-tag type="success" v-else-if="scope.row.level === '1'">二级</eltag>
<el-tag type="danger" v-else>三级</el-tag>
</template>
</el-table-column>
</el-table>
</el-card>
</div>
</template>
<script>
export default {
data() {
return {
// 权限列表
rightsList: []
};
},
created() {
this.getRightsList();
},
methods: {
async getRightsList() {
//获取权限列表数据
const { data: res } = await this.$http.get("rights/list");
if (res.meta.status !== 200) {
return this.$message.error("获取权限列表失败!");
}
this.rightsList = res.data;
}
}
};
</script>
<style lang='less' scoped>
</style>
Vue用的哪种设计模式
属于发布订阅模式,在vue中使用observer和definereactive两个方法的结合对数据进行递归劫持,然后通过watch这个类来对属性进行订阅,Dep类用于解耦合,当数据变更的时候先触发数据的set方法,然后调用Dep.notiify通知视图更新
说说vue操作真实dom性能瓶颈
vue性能瓶颈的几种情况
1. 一次渲染大量的数据的时候,存在大量数据并且都是复杂类型的时候,会导致vue对数据的劫持时间和渲染时间变长, js 连续执行时间过长,会导致页面长时间无法交互,而且渲染时间太慢,用户一次交互反馈的时间过长。
优化方案:可以使用 requestAnimation 这个方法,将数据进行分割,分批次渲染,减少了 js 的
连续运行时间,并且加快了渲染时间,利用加长总运行时间换取了渲染时间,用户既能快速
得到反馈,而且不会因为过长时间的 js 运行而无法与页面交互。
2. 当页面中存在大量数据,只是修改了一小部分导致页面也会导致页面卡顿,因为vue的更新以组件为粒度进行更新的,只要修改了当前组件中所使用的数据,组件就会整个去进行更新,造成大量的时间浪费
优化方案:将不同的模块划分成不同的组件,这样有效降低虚拟dom的diff运算时间过长的问题,
比如将大量数据的模块单独放一个组件,其它放一个组件,由于vue是以组件为粒度更新,修改
其它组件的情况下不会导致table的重新diff,提升页面响应速度高达几百倍
3. 动态插槽作用域或者静态插槽的更新
使用插槽作用域来替换这两种操作方式,一样能提升性能,因为使用 插槽作用域 之后,插槽内容
会被封装到一个函数中,被子组件渲染,而不是在父组件
Vue中如何获取dom、操作dom、更新dom
如何获取dom?在Vue中提供了一种特别的方式来获取dom,即给dom加上个ref属性,那么就可以通过this.$refs.名字来获取到该dom元素。
如何操作dom、更新dom?通过refs.名字就可以拿到对应的真实dom,然后就可以用原生JS进行操作和更新。当然vue框架本身就是不需要dom操作的,通过修改相应的数据并再配合指令、模板语法就可以轻松的操作和更新dom。
Vue 的双向数据绑定原理是什么
在Vue2.x中,双向数据绑定是通过 数据劫持 结合 发布订阅模式的方式来实现的,也就是说数据和视图同步,数据发生变化,视图跟着变化,视图变化,数据也随之发生改变。核心:关于VUE双向数据绑定,
其核心是 Object.defineProperty()方法。
Vue3.x则是用ES6的语法Proxy对象来实现的。
Object.defineProperty()的缺点:
1. 只能监听对象(Object),不能监听数组的变化,无法触发push, pop, shift, unshift,splice, sort,reverse。
2. 必须遍历对象的每个属性
3. 只能劫持当前对象属性,如果想深度劫持,必须深层遍历嵌套的对象。
Proxy的优点:
1. Proxy 可以直接监听对象而非属性。
2. Proxy 可以直接监听数组的变化。
3. Proxy 有多达 13 种拦截方法,不限于 apply、ownKeys、deleteProperty、has 等等是
Object.defineProperty 不具备的。
4. Proxy 返回的是一个新对象,我们可以只操作新的对象达到目的,而 Object.defineProperty 只能遍历对象属性直接修改。
5. Proxy 作为新标准将受到浏览器厂商重点持续的性能优化,也就是传说中的新标准的性能红利。
let arr = [];
let proxy = new Proxy(arr, {
get: function(obj, prop){
return obj[prop];
},
set: function(obj, prop, value){
obj[prop] = value; //可以被监听到变化
return true;
}
});
setTimeout(()=>{
proxy.push(1);
}, 2000)
vue中为什么用虚拟dom而不操作真实dom
起初我们在使用JS/JQuery时,不可避免的会大量操作DOM,而DOM的变化又会引发回流或重绘,从而降低页面渲染性能。那么怎样来减少对DOM的操作呢?此时虚拟DOM应用而生,所以虚拟DOM出现的主要目的就是为了减少频繁操作DOM而引起回流重绘所引发的性能问题的!
虚拟DOM(Virtual Dom),起始本质上就是一个JS对象,当数据发生变化时,我们不直接操作真实DOM,因为很昂贵,我们去操作这个JS对象,就不会触发大量回流重绘操作,再加上diff算法,可以找到两次虚拟DOM之间改变的部分,从而最小量的去一次性更新真实DOM,而不是频繁操作DOM,性能得到了大大的提升。
虚拟DOM还有一个好处,可以渲染到 DOM 以外的平台,实现 SSR、同构渲染这些高级特性,Weex 等框架应用的就是这一特性。
Vue如何进行组件传值
父向子组件传值,可以利用prop方式。
子向父组件传值,可以利用自定义事件$emit方式。
多层级组件传值,可以使用provide/inject
无关系的组件传值,利用vuex状态管理
谈谈如何实现vue组件通信和传值方式 (两个问题为同一个答案问法不一样)
这类问题 首先分类 表明了解的比较多 具体就没说完 或者漏了 面试官也不会计较很多
组件通信的四大类 父与子 子与父 子与子 跨层级
在细说各种方式 加入自己的理解
1、props和$emit
父组件向子组件传递数据是通过prop传递的,子组件传递数据给父组件是通过$emit触发事件
2、$attrs和$listeners
3、中央事件总线 bus
上面两种方式处理的都是父子组件之间的数据传递,而如果两个组件不是父子关系呢?这种情况下可以使用中央事件总线的方式。新建一个Vue事件bus对象,然后通过bus.$emit触发事件,bus.$on监听触发的事件。
4、provide和inject
父组件中通过provider来提供变量,然后在子组件中通过inject来注入变量。不论子组件有多深,只要调用了inject那么就可以注入provider中的数据。而不是局限于只能从当前父组件的prop属性来获取数据,只要在父组件的生命周期内,子组件都可以调用。
5、v-model
父组件通过v-model传递值给子组件时,会自动传递一个value的prop属性,在子组件中通过
this.$emit(‘input’,val)自动修改v-model绑定的值
6、$parent和$children
7、boradcast和dispatch
8、vuex处理组件之间的数据交互 如果业务逻辑复杂,很多组件之间需要同时处理一些公共的数据,这个时候才有上面这一些方法可能不利于项目的维护,vuex的做法就是将这一些公共的数据抽离出来,然后其他组件就可以对这个公共数据进行读写操作,这样达到了解耦的目的。
说说vue中Key值的作用
关于这个可以的key的作用 首先表明 key 不是一定要有的 不写可以代码也可以跑 但是建议加上
然后指出可以用的地方 key在v-for循环可以用用 在表单元素中也可以用key 减少缓存
一般说key 只要说配合v-for的使用
key是为Vue中的vnode标记的唯一id,通过这个key,我们的diff操作可以更准确、更快速diff算法的过程中,先会进行新旧节点的首尾交叉对比,当无法匹配的时候会用新节点的key与旧节点进行比对,然后超出差异能讲清楚diff算法就继续讲
diff程可以概括为:oldCh和newCh各有两个头尾的变量StartIdx和EndIdx,它们的2个变量相互比较,一共有4种比较方式。如果4种比较都没匹配,如果设置了key,就会用key进行比较,在比较的过程中,变量会往中间靠,一旦StartIdx>EndIdx表明oldCh和newCh至少有一个已经遍历完了,就会结束比较,这四种比较方式就是首、尾、旧尾新头、旧头新尾.
准确: 如果不加key,那么vue会选择复用节点(Vue的就地更新策略),导致之前节点的状态被保留下来,会产生一系列的bug. 快速: key的唯一性可以被Map数据结构充分利用,相比于遍历查找的时间复杂度O(n),Map的时间复杂度仅仅为O(1)
讲完以后 还要补充一点自己的看法
建议使用主键比如id
当修改data时Vue的组件重渲染是异步还是同步
这个问题很有意思 因为平时我们一般问题异步和同步指的是 数据请求 同步和异步问题
这里加上了组件 还有修改data 这里给大家写个例子
以此可以说明
数据更新是同步的 但是视图更新是异步的
解决这个问题需要使用 $nextTick 解决视图异步更新的问题
Vue 组件懒加载,图片懒加载
组件懒加载
1. 结合路由插件使用的时候使用 import 方式实现
图片懒加载
就是在加载页面的时候,如果页面中的图片过多,可以使用占位符的方式替换没有在可是区域内的图片,只加载当前需要现实的图片。监听滚动条的位置,当图片标签出现在可视区域的时候,重置图片的路径为真是路径,然后展示图片地址。一般在实际开发的时候都直接使用图片懒加载插件实现。还有一种解决方案就是使用页面骨架屏效果,也是类似占位显示,当数据加载完成之后替换掉占位显示的内容
vuex做数据集中管理,mutations和actions分别是做什么的,为什么不能用mutations处理异步数据
? mutations和actions分别是做什么的?
mutations和action都是用来改变Vuex store的状态的;mutations提供的回调函数是同步的;而actions提供的方法是异步的,此外,actions的方法最终还是通过调用mutations的方法来实现修改vuex的状态的。
? 为什么不能用mutations处理异步数据?
官方文档说明:“在 mutation 中混合异步调用会导致你的程序很难调试。例如,当你能调用了两个包含异步回调的 mutation 来改变状态,你怎么知道什么时候回调和哪个先回调呢?这就是为什么我们要区分这两个概念。在 Vuex 中,我们将全部的改变都用同步方式实现。我们将全部的异步操作都放在Actions中。”
actions 和 mutations 并不是为了解决竞态问题,而是为了能用 devtools 追踪状态变化。事实上在 vuex 里面 actions 只是一个架构性的概念,并不是必须的,说到底只是一个函数,你在里面想干嘛都可以,只要最后触发 mutation 就行。
异步竞态怎么处理那是用户自己的事情。vuex 真正限制你的只有 mutation 必须是同步的这一点(在 redux 里面就好像 reducer 必须同步返回下一个状态一样)。同步的意义在于这样每一个 mutation 执行完成后都可以对应到一个新的状态(和 reducer 一样),这样 devtools 就可以打个snapshot 存下来,然后就可以随便 time-travel 了。如果你开着 devtool 调用一个异步的 action,你可以清楚地看到它所调用的 mutation 是何时被记录下来的,并且可以立刻查看它们对应的状态。其实我有个点子一直没时间做,那就是把记录下来的 mutations 做成类似 rx-marble 那样的时间线图,对于理解应用的异步状态变化很有帮助。
写公用组件的时候,怎么提高可配置性
1. 带着开放封闭原则的视角思考
开放原则,是说我们需要将有可能变动的属性,通过props接口的方式暴露给组件的调用者。
封闭原则,意思是我们需要将该组件的通用能力及逻辑封装再组件内部,让调用者使用更加方便
2. 组件的可配置性需要结合实际的业务需求具体分析
假设我们要封装一个Tab选项卡组件,实际功能交互可参考组件 | Element
3. 组件的开放原则实践
上面的表格为Tab组件提供的props配置接口,它们需要遵循如下特点,可以极大提高可配置性:
- 配置项要尽可能多的,覆盖到业务中可能出现的每一种情况。
- 保证组件在每一项配置缺省状态下都能够正常表现
- 每一项配置都应该具备合理的默认值。
1. 组件的封闭原则实践
上面的表格为Tab组件所提供的自定义事件,但是事件相关的逻辑实现,已经完全在组件内部封装好了,组件使用者,只需要按需绑定事件即可对组件的行为做出监听,这些事件也需要遵循如下特点,才能保证该组件的可配置性:
- 事件函数相关逻辑,必须在组件内部封装完善
- 自定义事件函数在触发时,必须能够返回相关的参数
例如 @tab-click 事件会给函数返回,被点击菜单的index下标等信息
- 事件函数本身也需要能够在缺省状态下,保持组件的正常运行。
no.2 React中大厂常见面试题
说说React中onClick绑定后的工作原理
1. 首先react有自己的事件系统,也是遵循w3c的,这个事件系统的名称叫做合成事件(SyntheticEvent),而其自定义事件系统的动机主要包含以下几个方面
- 抹平不同浏览器之间的兼容性差异。最主要的动机。
- 件合成既可以处理兼容性问题
- 提供一个抽象的跨平台事件机制
- 可以做更多优化
- 可以干预事件的分发
2. 当给组件(元素)绑定 onClick 事件之后
1. react会对事件先进行注册,将事件统一注册到 document 上
2. 根据组件 唯一的标识key 来对事件函数进行存储
3. 统一的指定 dispatchEvent 回调函数
4. 储存事件回调: react会将click 这个事件统一存到一个对象中,回调函数的存储采用键值对
(key/value)的方式存储在对象中,key 是组件的唯一标识 id,value 对应的就是事件的回
调函数,通过组件的key就能回调到相应的函数了
说说react里面bind与箭头函数
1. bind 由于在类中,采用的是 严格模式 ,所以事件回调的时候 会丢失this指向,指向undefined ,需要使用bind来给函数绑定上当前实例的this指向
2. 箭头函数 的this指向上下文,所以永久能拿到当前组件实例的 this 指向,我们可以完美的使用箭头函数来替代传统事件处理函数的回调
usememo在react中怎么使用
返回一个 memoized 值。
把“创建”函数和依赖项数组作为参数传入 useMemo,它仅会在某个依赖项改变时才重新计算 memoized值。这种优化有助于避免在每次渲染时都进行高开销的计算。
传入 useMemo 的函数会在渲染期间执行。请不要在这个函数内部执行与渲染无关的操作,诸如副作用这类的操作属于 useEffect 的适用范畴,而不是 useMemo。
如果没有提供依赖项数组,useMemo 在每次渲染时都会计算新的值。
你可以把 useMemo 作为性能优化的手段,但不要把它当成语义上的保证。将来,React 可能会选择“遗忘”以前的一些 memoized 值,并在下次渲染时重新计算它们,比如为离屏组件释放内存。先编写在没有useMemo 的情况下也可以执行的代码 —— 之后再在你的代码中添加 useMemo,以达到优化性能的目的。
react常用的优化手段有哪些
1. 属性传递优化
2. 多组件优化
3. Key
4. memo
5. purecomponent
6. 生命周期
7. 虚拟列表
8. 使用纯组件
9. 懒加载组件
10. 使用 React Fragments 避免额外标记
11. 不要使用内联函数定义
12. 避免 componentWillMount() 中的异步请求
13. 在 Constructor 的早期绑定函数
14. 优化 React 中的条件渲染15. 不要在 render 方法中导出数据
16. 为组件创建错误边界
17. 组件的不可变数据结构
类组件和函数组件的区别
1. 函数组件看似只是一个返回值是DOM结构的函数,其实它的背后是无状态组件(StatelessComponents)的思想。函数组件中,你无法使用State,也无法使用组件的生命周期方法,这就决定了函数组件都是展示性组件(Presentational Components),接收Props,渲染DOM,而不关注其他逻辑。
2. 函数组件中没有this。所以你再也不需要考虑this带来的烦恼。而在类组件中,你依然要记得绑定this这个琐碎的事情。如示例中的sayHi。
3. 函数组件更容易理解。当你看到一个函数组件时,你就知道它的功能只是接收属性,渲染页面,它不执行与UI无关的逻辑处理,它只是一个纯函数。而不用在意它返回的DOM结构有多复杂。
4. 性能。目前React还是会把函数组件在内部转换成类组件,所以使用函数组件和使用类组件在性能上并无大的差异。但是,React官方已承诺,未来将会优化函数组件的性能,因为函数组件不需要考虑组件状态和组件生命周期方法中的各种比较校验,所以有很大的性能提升空间。
5. 函数组件迫使你思考最佳实践。这是最重要的一点。组件的主要职责是UI渲染,理想情况下,所有的组件都是展示性组件,每个页面都是由这些展示性组件组合而成。如果一个组件是函数组件,那么它当然满足这个要求。所以牢记函数组件的概念,可以让你在写组件时,先思考这个组件应不应该是展示性组件。更多的展示性组件意味着更多的组件有更简洁的结构,更多的组件能被更好的复用。
在React组件复用与组合 中我们会提到,应当避免在底层的展示性组件中混入对于状态的管理,而应该将状态托管于某个高阶组件或者其他的状态容器中。利用函数式声明组件可以彻底保证不会在组件中进行状态操作。
双向数据绑定和单向数据流的优缺点
1. 单向数据流 数据流动方向可以跟踪,流动单一,追查问题的时候可以跟快捷。缺点就是写起来不太方便。要使UI发生变更就必须创建各种action来维护对应的state
2. 单向数据流其实是没有状态的, 这使得单向绑定能够避免状态管理在复杂度上升时产生的各种问题,程序的调试会变得相对容易, 但强制要求编码时设计思维的一致性。
3. 双向流动值和UI双绑定,这种好处大家都懂。但是由于各种数据相互依赖相互绑定,导致数据问题的源头难以被跟踪到,子组件修改父组件,兄弟组件互相修改有有违设计原则。 但好处就是 太方便使用了。
4. 双向数据流是自动管理状态的, 但是在实际应用中会有很多不得不手动处理状态变化的逻辑, 使得程序复杂度上升, 难以调试, 但程序各个部分自成一体, 不强制要求一致的编码。
如果你的程序需要一个统一的数据源, 应该选择单向数据流, 所有的数据变化都是可观测的, 数据自上而下流动, 即使出问题也很容易找到源头.
5. 如果你的程序本身有多个数据源, 或者是程序的逻辑本身会产生很多的副作用, 应该选择双向绑定的程序, 将大项目分化为小项目, 逐个击破。
6. 单向绑定使得数据流也是单向的,对于复杂应用来说这是实施统一的状态管理(如redux)的前提。
双向绑定在一些需要实时反应用户输入的场合会非常方便(比如多级联动菜单)。但通常认为复杂应用中这种便利比不上引入状态管理带来的优势。
redux和context+hooks优缺点
数据流对比
redux
简单分析
redux 的数据流程图画得比较简单,理解大概意思就好,毕竟它不是我要说的重点,和 hooks 的数据流程相比其实是大同小异。
从 hooks 数据流能大致看出来,我们设计好 store 后,通过对应的 hooks 函数生成每个 store 的Provider 和 Context。我们把所有的单个 Provider 糅合为一个整体的 Providers,作为所有 UI 的父组件。
在任何一个子 UI 组件内部,通过 hooks 函数得到对应 store 的 state、dispatch。UI 组件内,通过主动调用 dispatch 发送 action,然后经过 store 的数据处理中心 reducer,就能触发相应的数据改变。
这个数据流程和 redux 几乎一模一样。
相同点
统一 store 数据管理
支持以发送 action 来修改数据
支持 action 处理中心:reducer
异同点
hooks UI 层获取 store 和 dispatch 不需要用 HOC 依赖注入,而是用 useContext
redux 在 action 之后改变视图本质上还是 state 注入的方式修改的组件内部 state,而 hooks 则是一对一的数据触发
hooks 的 reducer 来自于 useReducer
hooks 还没有 middleware 的解决方案
react的生命周期
react旧版生命周期包含三个过程
1、挂载过程
constructor()
componentWillMount()
componentDidMount()
2、更新过程
componentWillReceiveProps(nextProps)
shouldComponentUpdate(nextProps,nextState)
componentWillUpdate (nextProps,nextState)
render()
componentDidUpdate(prevProps,prevState)
3、卸载过程
componentWillUnmount()
其具体作用分别为:
1、constructor()
完成了React数据的初始化。2、componentWillMount()
组件已经完成初始化数据,但是还未渲染DOM时执行的逻辑,主要用于服务端渲染。
3、componentDidMount()
组件第一次渲染完成时执行的逻辑,此时DOM节点已经生成了。
4、componentWillReceiveProps(nextProps)
接收父组件新的props时,重新渲染组件执行的逻辑。
5、shouldComponentUpdate(nextProps, nextState)
在setState以后,state发生变化,组件会进入重新渲染的流程时执行的逻辑。在这个生命周期中return
false可以阻止组件的更新,主要用于性能优化。
6、componentWillUpdate(nextProps, nextState)
shouldComponentUpdate返回true以后,组件进入重新渲染的流程时执行的逻辑。
7、render()
页面渲染执行的逻辑,render函数把jsx编译为函数并生成虚拟dom,然后通过其diff算法比较更新前后的新旧DOM树,并渲染更改后的节点。
8、componentDidUpdate(prevProps, prevState)
重新渲染后执行的逻辑。
9、componentWillUnmount()
组件的卸载前执行的逻辑,比如进行“清除组件中所有的setTimeout、setInterval等计时器”或“移除所有组件中的监听器removeEventListener”等操作。
react新版生命周期
react16.4后使用了新的生命周期,使用getDerivedStateFromProps代替了旧的componentWillReceiveProps及componentWillMount。使用getSnapshotBeforeUpdate代替了旧的componentWillUpdate。
使用getDerivedStateFromProps(nextProps, prevState)的原因:
旧的React中componentWillReceiveProps方法是用来判断前后两个 props 是否相同,如果不同,则将新的props 更新到相应的 state 上去。在这个过程中我们实际上是可以访问到当前props的,这样我们可能会对this.props做一些奇奇怪怪的操作,很可能会破坏 state 数据的单一数据源,导致组件状态变得不可预测。而在 getDerivedStateFromProps 中禁止了组件去访问 this.props,强制让开发者去比较 nextProps 与prevState 中的值,以确保当开发者用到 getDerivedStateFromProps 这个生命周期函数时,就是在根据当前的 props 来更新组件的 state,而不是去访问this.props并做其他一些让组件自身状态变得更加不可预测的事情。
使用getSnapshotBeforeUpdate(prevProps, prevState)的原因:
在 React 开启异步渲染模式后,在执行函数时读到的 DOM 元素状态并不总是渲染时相同,这就导致在componentDidUpdate 中使用 componentWillUpdate 中读取到的 DOM 元素状态是不安全的,因为这时的值很有可能已经失效了。
而getSnapshotBeforeUpdate 会在最终的 render 之前被调用,也就是说在 getSnapshotBeforeUpdate 中读取到的 DOM 元素状态是可以保证与componentDidUpdate 中一致的。
怎么用 React-redux 解决数据发生改变就会刷新页面这个问题
通常情况下,store 状态数据发生改变,会刷新页面这个问题是由于设计导致的,可能是组件定义时的问
题。建议不要将页面中使用的组件都包装到一个大的容器组件中(如图1所示),而是将各相关的组件包
装到一个较小的容器组件中(如图2所示):
图1中,当容器组件中订阅的 store 发生变化时,所有组件都会重新渲染。在图2中,由于将相关组件包装到了较小的容器组件中,当 container2 容器中订阅的 store 发生变化时,仅相关的组件重新渲染,其它组件不会导致重新渲染。
写在最后
因为文章写再多你们刷起来也不自在,所以有pdf版本,类似的也有,五一过了,马上6月份,没有工作的宝子要注意时间,趁早上岸,早点拿到offer也放心,另外就是简历方面的问题,简历也很重要,还有项目,需要帮忙可以【点击此处】哦
好了,今天的文章到此结束,我们下次再约。