Vue组件通信
- 父子组件通信 props
- 子父组件通信 $emit
- 非父子组件通信
- ref
- bus事件总线
- 多组件状态共享 vuex
面试题: 你是否了解虚拟DOM?
- 虚拟DOM是什么?
- 我们使用js对象模型来模拟真实DOM,那么这个对象模型就是虚拟DOM
- 虚拟DOM为什么性能高?
- 因为我们操作的是虚拟DOM,大大减少真实DOM操作,那么就会节省内存,降低消耗
- 虚拟DOM工作流程[ vue/react ]
- vue
- 根据模板 -> 创建VDOM[ jsx ]
- render函数渲染jsx -> 虚拟dom对象模型
- 在mounted渲染真实DOM
- 当data选项数据改变时
- 在一次生成VDOM
- 通过diff算法【 使用js进行同级比较 】比对生成patch补丁对象
- 根据patch补丁对象重新渲染真实DOM
- React
- 根据模板 -> 创建VDOM[ jsx ]
- render函数渲染jsx -> 虚拟dom对象模型
- 在componentDidMount渲染真实DOM
- 当data发生改变时
- 在一次生成vdom
- 通过 React Filber【 React 16版本使用 】 算法进行比较,生成patch补丁对象
- 根据patch补丁对象重新渲染真实DOM
- vue
React 15 vs React 16 [ 扩展 ]
- 生命周期有区别
- React15对属性和状态分别使用的是: getDefaultProps 和 getInitalState, 而16版本统一生成constructor
- React16版本之后新增了一个错误处理阶段: componentDidCatch
- React 15采用diff算法, React16之后采用filber算法
- React15使用React.createClass 来创建类组件,而16使用class xx extends Component 来创建类组件
React生命周期16版本
-
初始化阶段 - 自动执行
- constructor 继承属性 定义状态 绑定事件this
- componentWillMount
- render 生成vdom 计算 this.props this.state
- componentDidMount 数据请求 - 数据修改 - 获取真实DOM
-
更新阶段 - 数据改变
- componentWillReceiveProps [ 属性改变才执行 ] 接收新属性, 判断组件属性是否改变,可以用于监听
- shouldComponentUpdate 性能优化关键钩子函数 , 控制组件是否要更新
- componentWillUpdate
- render
- componentDidUpdate 获得了更新后的真实dom
-
销毁阶段
- componentWillUnmount 组件销毁, 善后
-
错误处理阶段
- componentDidCatch 记录错误信息和错误栈 、
- 功能实现降级UI
React高阶组件 - HOC
- 全称: Height Order Component
- 作用:
- 将多个组件需要的方法或是组件进行封装,然后复用
React Filber 算法是什么?
- 概念
- 将一个大的任务分成多个小片,然后执行每一个小片,每一个小片执行时间很短,总时间很长,但是给其他任务提供了可以执行的机会
React 特点
- 虚拟DOM
- 组件系统
- 单项数据流 - 组件系统
- JSX语法
函数式组件 React Hooks
为什么要使用React Hooks?
- 我们想要在函数式组件中使用类组件的一些功能,比如: 状态定义、生命周期
- react Hooks目的是为了让我们能够在函数式组件中使用类组件功能
出现时间 - React 16.8 版本之后才出现的【 到现在大概半年左右 】
React提供了哪些Hooks呢?
- useState 定义状态
- useEffect 使用生命周期【 componentDidMount componentWillUnmount componentDidUpdate 】
- useRef 获得组件
- 可以让我们在函数式组件中通过ref绑定得到元素或是组件
- useContext 使用上下文 Context
- useReducer
- useCallback
- useMemo
- useImperativeHandle
- useLayoutEffect
- useDebugValue
ref
- 功能是绑定一个组件或是元素,让我们可以获得它们的实例,
- 组件仅仅只能是类组件
promise
Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。
所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。
Promise对象有以下两个特点。
(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。
(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。
前端拷贝
-
类型
- 浅拷贝: 只拷贝一层的拷贝方式,地址拷贝
- 深拷贝: 值的完全拷贝
-
浅拷贝实现
- 解构赋值
- Object.assign
- 引用类型直接赋值
-
深拷贝实现
- JSON.parse / JSON.string [ 序列化 / 反序列化 ]
- 递归实现深拷贝 - 要求: 手写出来
//对象深拷贝 function deepClone(origin,target){ //target是否存在如果不存在创建空对象 let tar = target || {}, //判断是否为引用数据类型 toStr = Object.prototype.toString, arrType='[object Array]'; for(let key in origin){ //剥离原型链的数据 if(origin.hasOwnProperty(key)){ //判断是否为引用数据类型 对象或数组 if(typeof(origin[key]) === 'object' && origin[key] !== null){ if(toStr.call(origin[key]) === arrType ){ tar[key] = []; }else{ tar[key] = {}; } deepClone(origin[key],tar[key]); }else{ tar[key] = origin[key]; } } } return tar; }
- 第三方
- loadsh
- _.cloneDeep()
- Immutable.js 【 性能最好的 】
- loadsh
connect方法的原理
- connect调用的结果是返回一个高阶组件
- connect方法利用了合并分发的原理来帮助我们完成store内容的获取
- 合并: 将store中的所有数据拿到手
- 分发: 将我们UI需要的数据派发出去
redux中数据请求你是如何处理的?
- 使用redux-thunk 或是 redux-saga