es6学习1: 模拟react Comopnent类的实现
开始系统学习es6, 按自己的理解简单模拟个react的Component类和生命周期思维, 见证自己的成长, 初学, 写着娱乐, 勿喷 T.T
test.js
import mm from '../util/util.js'; class Component{ constructor(props) { this.props = {}; // 注入的history等 this.props = Object.assign(this.props, props || {}); this.state = {}; this.loadComponent(); } setState(obj, fallBack){ // 判断是否需要刷新虚拟dom if (this.shouldComponentUpdate(obj)) { this.componentUpdate(); Object.assign(this.state,obj); this.componentDidUpdate(); this.loadComponent(); } // 调用回调函数 typeof fallBack === 'function' && fallBack(); } loadComponent() { this.componentWillUMount(); this.loadProps(); this.componentDidUMount(); } loadProps(){} flushVdom(){} // 声明周期函数 shouldComponentUpdate(obj){ console.log("shouldComponentUpdate"); // 对象深拷贝 let stateCopy = mm.objDeepCopy(this.state); // 合并对象 let objResult = Object.assign(stateCopy, (obj || {})); // 将setstate的值和state的值合并看和原state的值是否相等 if (mm.isEqual(objResult,this.state)) { // 不相等就不刷新组件 console.log("值相等: 不刷新虚拟dom"); return false; } console.log("值不等, 刷新虚拟dom"); this.flushVdom(); // 不相等就刷新组件 return true; } componentUpdate(){ console.log('componentWillUpdate'); } componentDidUpdate(){ console.log('componentDidUpdate'); } componentWillUMount(){ console.log('componentWillMount'); } componentDidUMount(){ console.log('componentDidMount'); } } class Test2 extends Component{ constructor(props){ super(props); } render(){ this.setState( {name:'avenda'}, ()=>(console.log("setState后的回调方法...")) ); return(`<div>我是得到的标签</div>`) } } // 模拟调用 console.log(new Test2().render());
工具类 util.js (对象深拷贝及isEquels方法)
let mm = { isEqual(a, b) { //如果a和b本来就全等 if (a === b) { //判断是否为0和-0 return a !== 0 || 1 / a === 1 / b; } //判断是否为null和undefined if (a == null || b == null) { return a === b; } //接下来判断a和b的数据类型 var classNameA = toString.call(a), classNameB = toString.call(b); //如果数据类型不相等,则返回false if (classNameA !== classNameB) { return false; } //如果数据类型相等,再根据不同数据类型分别判断 switch (classNameA) { case '[object RegExp]': case '[object String]': //进行字符串转换比较 return '' + a === '' + b; case '[object Number]': //进行数字转换比较,判断是否为NaN if (+a !== +a) { return +b !== +b; } //判断是否为0或-0 return +a === 0 ? 1 / +a === 1 / b : +a === +b; case '[object Date]': case '[object Boolean]': return +a === +b; } //如果是对象类型 if (classNameA == '[object Object]') { //获取a和b的属性长度 var propsA = Object.getOwnPropertyNames(a), propsB = Object.getOwnPropertyNames(b); if (propsA.length != propsB.length) { return false; } for (var i = 0; i < propsA.length; i++) { var propName = propsA[i]; //如果对应属性对应值不相等,则返回false if (a[propName] !== b[propName]) { return false; } } return true; } //如果是数组类型 if (classNameA == '[object Array]') { if (a.toString() == b.toString()) { return true; } return false; } }, // 对象深拷贝 objDeepCopy (data) { return JSON.parse(JSON.stringify(data)); } } export default mm;
测试
调用 setState({},()=>( console.log("setState后的回调方法...") ) 输出结果
调用 setState({name:'avenda'},()=>( console.log("setState后的回调方法...") ) 输出结果
能敲代码, 时不时画画, 时而玩玩户外, 拍拍喜欢的景象, 人生, 就够了...