一、Redux
- 是什么?
- redux是一个使用叫做‘action'的事件来管理和更新应用状态的模式和工具库。它以集中式store的方式对整个应用中使用的状态进行集中管理,其规则确保状态只能以可预测的方式更新。
- 而在整个应用中会存在很多个组件,每个组件的state是由自身进行管理,包括组件定义自身的state、组件之前的通信通过props传递、使用Context实现数据共享。
- 如果让每个组件都存储自身相关的状态,理论上来讲不会影响应用的运行,但在开发及后续维护阶段,我们将花费大量精力去查询状态的变化过程。
- 这种情况下,如果将所有的状态进行集中管理,当需要更新状态的时候,仅需要对这个管理集中处理,而不用去关系状态是如何分发到每一个组件内部的。
- redux就是一个实现上述集中管理的容器,遵循三大基本原则:
- 单一数据源
- state是只读的
- 使用纯函数来执行修改
注意:redux并不是只应用在react中,还与其他界面库一起使用,如vue
- 什么情况下建议使用redux
- 应用中有很多state在多个组件中需要使用
- 应用state会随着时间的推移而频繁更新
- 更新state的逻辑很复杂
- 中型和大型代码量的应用,很多人协同开发
- 有很多数据随时间而变化
- 希望状态有一个唯一确定的来源
- 将所有状态放在顶层组件中管理已不可维护
- 工作原理
- redux要求我们把数据都放在store公共存储空间
- 一个组件改变了store里的数据内容,其他组件就能感知到store的变化,再来取数据,从而间接的实现了这些数据传递的功能。
- 步骤
- 初始启动
- 使用最顶层的root reducer函数创建redux store
- store调用一次root reducer,并将返回值保存为它的初始值
- 当视图首次渲染时,视图组件访问Redux store的当前state,并使用该数据来决定要呈现的内容。同时监听store的更新,以便它们可以知道state是否已更改。
- 更新环节
- 应用程序中发生了某些事情,例如用户单击按钮
- dispatch一个action到Redux store,例如dispatch({ type: 'counter/increment' })
- store用之前的state和当前的action再次运行reducer函数,并将返回值保存为新的state
- store通知所有订阅过的视图,通知它们store发生更新
- 每个订阅过store数据的视图,组件都会检查它们需要的state部分是否被更新
- 发现数据被更新的每个组件都强制使用新数据重新渲染,紧接着更新网页
- 一些概念
- Redux是一个管理全局应用状态的库
- Redux通常与React-Redux库一起使用,把Redux和React集成在一起
- Redux Toolkit是编写Redux逻辑的推荐方式
- Redux使用”单项数据流“
- State描述了应用程序在某个时间点的状态,视图基于该state渲染
- 当应用程序中发生某些事情时:
- 视图dispatch一个action
- store调用reducer,随后根据发生的事情来更新state
- store将state发生了变化的情况通知UI
- 视图基于新state重新渲染
- Redux有这几种类型的代码
- Action是有type字段的纯对象,描述发生了什么
- Reducer是纯函数,基于先前的state和action来计算新的state
- 每当dispatch一个action后,store就会调用root reducer
- 规则
- 仅使用state和action参数计算新的状态值
- 禁止直接修改state。必须通过复制现有的state并对复制的值进行更改的方式来做不可变更新
- 禁止任何异步逻辑、依赖随机值或导致其他“副作用”的代码
- 在Redux中,永远不允许在reducer中更改state的原始对象
二、js函数和箭头函数有什么区别
- 语法更加简洁、清晰。箭头函数省去了function关键字,采用箭头=>来定义函数。
- 箭头函数不会创建自己的this
- 箭头函数没有自己的this,它会捕获自己在定义时(注意: 是定义时,不是调用时)所处的外层执行环境的this,并继承这个this值。所以,箭头函数中this的指向在它被定义时就已经确定了,之后永远不会改变。
- 箭头函数继承而来的this指向永远不变
- .call()|.apply()|.bind()无法改变箭头函数中this的指向
- 箭头函数不能作为构造函数使用
- 箭头函数没有自己的arguments
- 可以在箭头函数中使用rest参数代替arguments对象,来访问箭头函数的参数列表??
- 箭头函数没有原型prototype
- 箭头函数不能用作Generator函数,不能使用yeild关键字
三、海量数据显示:
分页、数据懒加载
四、echarts常用的api?
- 常用的图标类型
- 柱状图
- 折线图
- 饼图
- 散点图
五、浏览器缓存
浏览器缓存是浏览器在本地磁盘对用户最近请求过的文档进行存储,当访问者再次访问同一页面时,浏览器就可以直接从本地磁盘加载文档。
- 强缓存(本地缓存)
- 当请求资源的时候,如果是之前请求过的并使用强缓存,那么在过期时间内将不会发送本次请求向服务器获取资源,而是直接从浏览器缓存中获取(不管资源是否改动)。过期了将重新从服务器获取,并再次强缓存。
- 协商缓存(弱缓存)
- 当请求资源的时候,如果是之前请求过的并使用协商缓存,还是发送请求到服务器,服务器通过逻辑判断确认资源没有修改返回304,本次的资源从缓存中读取;如果经过判断确认资源有被修改过,则重新发送资源到客户端,并且客户端更新缓存。
- 优点:
- 减少加载时间: 通过使用缓存, 浏览器可以重用已下载的资源, 而不必每次都从服务器重新请求。这减少了页面加载时间, 提高了用户体验, 尤其是在较慢的网络连接下。
- 降低服务器负载: HTTP缓存可以减少服务器的负载, 因为不再需要为相同的资源处理大量重复请求。这有助于减少服务器资源的使用, 降低运营成本。
- 减少网络流量: HTTP缓存可以减少不必要的网络流量, 因为浏览器可以从本地缓存中加载资源, 而不必每次都从服务器下载。这有助于减少带宽成本, 尤其是对于大型网站来说。
- 提高用户体验: 快速加载的网页提供更好的用户体验, 吸引更多的访问者, 并增加用户留存率。缓存使用户能够更快地访问网站内容, 从而提高了他们的满意度。
六、浏览器插件如何开发
一个 Chrome 插件通常由以下几个基本文件组成:
manifest.json:插件的配置文件,定义插件的基本信息和权限。 background.js:插件的后台脚本,负责执行后台任务。 popup.html:用户点击插件图标时显示的界面。 style.css:用于美化插件界面的样式表。
七、组件封装、插件封装、性能优化、打包优化
八、webpack打包相关
- 通过webpack.base.js提供基础配置,分别创建webpack.dev.js和webpack.prod.js实现开发和生产环境的差异化配置
- 在开发环境中引入webpack-hot-middleware实现热更新
- 通过webpack-merge插件合并基础配置与环境特定配置,提升代码可维护性
九、ts基础知识
- 类型系统
- 强类型与弱类型
- 强类型:不允许隐式类型转换
- 静态类型与动态类型
- 动态类型:运行阶段才能够明确变量类型,变量类型能随时发生变化(变量本身无类型,变量值有类型)
- JavaScript
- 弱类型、动态类型
- 常见问题
- 运行时才报错
- 类型不明确,造成函数功能发生改变
- 对象索引用法错误
- TypeScript
- JavaScript + ES6 + 类型系统
- 强类型优势
- 编译时报错
- 更加智能,编码更准确
- 重构更加牢靠
- 减少代码层面不必要的类型判断
- 缺点
- 语言本身多了很多概念,增加了学习成本
- 项目初期需要写很多类型声明
- 强类型与弱类型