react生命周期分为三个阶段:装载过程(Mount)、更新过程(update)、卸载过程(unmount)。
参考:https://blog.csdn.net/mafan121/article/details/77965379
父组件向子组件传参:props。
在父组件中向子组件添加属性,子组件通过this.props获取。
子组件向父组件传参:回调函数。
在父组件向子组件添加事件,子组件调用父组件事件并将参数带回。
HOC
是一个函数,其接收一个组件作为参数,返回一个增强的组件。
高阶组件主要被用于:代码模块化、代码复用、修改props、劫持渲染(操作state)。
常用的实现方式有:
示例:
import React, { Component } from 'react'
const withStorage = WrappedComponent => {
return class extends Component{
componentWillMount() {
let data = localStorage.getItem('data')
this.setState({ data })
}
render() {
return <WrappedComponent data={this.state.data} {...this.props} />
}
}
}
export default withStorage
这里采用属性代理的方式定义了一个高阶组件,其每个传入组件加载前都将去拿取
localStorage
的data
数据,避免了在每个组件中写componentWillMount
,提高了代码复用率。
react
中任何组件都有一个children属性
。他表示当前组件下的子元素,有点类似于innerHTML属性
。
this.props.children
的值有3种类型:undefined
(无子节点)、object
(一个子节点)、Array
(多个子节点)。
常用的方法:
React.Children.count(object children)
:返回子节点个数React.Children.map(object children, function fn [, object context])
:遍历children子元素,执行fn,并返回结果集。React.Children.forEach(object children, function fn [, object context])
:仅仅遍历子元素执行fn,无结果返回。React.Children.only(object children)
:返回children中仅有的子级,否则跑出异常。父组件调用子组件事件:refs。
为子组件绑定ref属性,在需要用到的时候通过
this.props.refs
属性获取到子组件,然后子组件就可以调用自己的事件了。
子组件调用父组件事件:props。
在父组件为子组件绑定事件,在子组件中通过this.props.事件名调用。
react diff算法分为3大策略,简化了比较的复杂度。
Tree diff
:通过updateDepth
对Virtual DOM
树进行层级控制,两棵树只进行同层节点比较,这样只需一次遍历即可完成整颗树的比较
component diff
:依旧根据层级比较,同类型的组件可通过shouldComponentUpdate
判断是否更新,不同类型组件直接替换。
element diff
:对同层的节点,可根据key值进行删除、插入、移动。
通过这三大策略,所有的比较可操作均在同一层级完成,大大节省了比较重绘时间。
redux:component --> dispatch(action) --> reducer --> subscribe --> getState --> component
参考:https://blog.csdn.net/mafan121/article/details/72673815
react-redux:component --> actionCreator(data) --> reducer --> component
connect(state => state, action)(Component);
参考:https://blog.csdn.net/mafan121/article/details/72830491
一个组件的所有数据都必须从父组件传递过来,不能像flux,从store中直接获取。
当一个组件相关的数据更新时,即使父组件不需要用到这个组件,父组件依旧需要重新render,这将导致渲染效率降低,需要通过shouldComponentUpdate
来优化。
redux将数据流规范了,所有数据均在store中管理,避免了父子组件不易传参的问题。
redux将流程规范了,减少了手动编码量。
内联元素:text-align:center;
块级元素:margin:0 auto;
或者绝对定位。
flex居中:display: flex; justify-content: center;
参考:https://blog.csdn.net/mafan121/article/details/53925555
单行元素:line-height:行高;
多行元素:绝对定位
flex居中:display: flex; align-items: center;
参考:https://blog.csdn.net/mafan121/article/details/53925555
flex居中:flex:1;
calc计算:calc(100%-200px)
;
浮动布局:float:left
;
定位布局:position:absolute;
参考:https://blog.csdn.net/mafan121/article/details/100057888
animation与display不兼容等。
参考:https://blog.csdn.net/mafan121/article/details/87795065
当然还有很多兼容性的属性,这里并没有列举,例如透明度:opacity等
盒子模式=外边距+边框+内边距+组件大小
box-sizing可以改变盒子模型。
参考:https://blog.csdn.net/mafan121/article/details/51548222
!important > 行内样式 > ID选择器 > 类选择器 > 元素 > 通配符 > 继承 > 浏览器默认属性
参考:https://blog.csdn.net/mafan121/article/details/48158001
link
是html标签
,只能存放于html源码
中,既可以加载css文件
,也能设置rss、rel等连接属性。在页面加载的时候同时被加载。可以通过dom操作插入。
@import
是CSS2.1中的语法,只有导入样式的作用,在页面加载完成后才开始加载。无法通过dom操作导入。
String、number、boolean、null、undefined、symbol
参考:https://blog.csdn.net/mafan121/article/details/48970993
事件委托又称事件代理,是利用事件冒泡原理,将子元素的事件绑定到父元素上,让父元素担当事件的监听者。然后通过特殊的子元素标识来区分目前触发的是哪个子元素事件。例如常见的点击浏览器任意位置关闭弹窗,就是将点击事件委托给了document对象。
优点是:
示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="http://lib.sinaapp.com/js/jquery/2.0.2/jquery-2.0.2.min.js"></script>
</head>
<body>
<ul id="myLinks">
<li id="goSomewhere">Go somewhere</li>
<li id="doSomething">Do something</li>
<li id="sayHi">Say hi</li>
</ul>
<script>
var ulEle = document.getElementById("myLinks");
ulEle.addEventListener("click", function (event) {
var target = event.target;
switch (target.id) {
case "doSomething":
document.title = "事件委托";
break;
case "goSomewhere":
location.href = "http://www.baidu.com";
break;
case "sayHi":
alert("hi");
break;
}
</script>
</body>
</html>
防抖:事件的执行必须间隔一定的时间,如果在指定时间内再次出发,则重新计时。
节流:在一段时间内,事件只能触发一次,时间段内的触发不生效。
参考:https://blog.csdn.net/mafan121/article/details/82115933
闭包是函数内部的函数,作用是防止变量污染。
参考:https://blog.csdn.net/mafan121/article/details/48243895
三者都是将数据缓存在浏览器端,但cookie数据存储量大约在4k左右,而storage存储量为5M左右。
cookie将会随http传递给后端,而storage仅仅是保存在本地,除非用户手动设置,否则不会传递给服务器。
storage:https://blog.csdn.net/mafan121/article/details/60133107
cookie:https://blog.csdn.net/mafan121/article/details/100062220
CommonJS
:是服务器端js模块化的规范,一个单独的文件就是一个模块,加载模块使用require
方法,该方法读取一个文件并执行,最后返回文件内部的exports
对象。NodeJs
采用该规范。
AMD
:异步模块定义,客户端js模块化的规范,只有一个接口:define(id?,dependencies?,factory);
需要在声明模块的时候制定所有的依赖(dep),并且还要当做形参传到factory中。通过define
定义,通过require
方法加载。RequireJS
采用这种规范。
CMD
:通用模块定义,客户端js模块化的规范,通过define
定义,通过require
方法加载。SeaJs
采用这种规范。
AMD和CMD的区别
AMD
提前执行,而CMD
则采用懒加载的方式延迟执行。require
,AMD
分全局require
和局部require
,CMD
中没有全局require
,而是按需加载。CMD
推崇依赖就近,AMD
推崇依赖前置。apply和 call都是以一个对象代替当前对象,调用当前对象的方法,实际上是变更了当前方法的this指向。
区别在于:出第一个参数外,call接收任何类型数据作为参数,且参数可以是多个,而apply只能接收数组作为参数,且只能有一个数组。
参考: https://blog.csdn.net/mafan121/article/details/52922149
浏览器同源策略导致了跨域问题,同时也减少了浏览器遭受的XSS、CSFR等攻击。
常见的解决方案:
参考:https://segmentfault.com/a/1190000011145364
1.代码抽离,提取公共代码,分离css代码。
2.Externals
第三方库外部引入。
3.减少loader筛选范围,精确resolve匹配路径,降低打包速度。
4.缓存loader的执行结果(cacheDirectory)
git 常用的命令:
git fetch <远程主机名> <分支名> //拉取远程分支到本地
git pull <远程主机名> <远程分支名> //拉取远程分支代码,并将远程分支代码和本地分支代码合并。
git checkout <分支名> //切换分支
git merge <分支名> //合并分支到当前分支
git add . //获取所有修改的文件
git commit -m "描述" //提交修改
git push origin <分支名> //推送代码到远端服务器
git commit --no-verify -m "提交描述"
(跳过eslint或tslint校验)
svn常用命令:
svn checkout //切换到服务器指定目录
svn add //获取需要提交的文件
svn commit -m "描述" //提交文件
svn update -r m //更新版本
svn lock -m “描述” [--force] //加/解锁
svn delete -m “描述” //删除文件
svn log //显示该文件的修改日志
svn svn merge -r m:n //合并2个版本中的指定文件
svn diff //比较当前文件和基础版本文件的差异