2019-06-04

一、Vue原理:4部分:

1.通过document.createDocumentFragment()创建虚拟dom树。

2. 检测数据改变通过object.defineProperty定义的数据拦截,截取到数据的变化。

3.然后通过发布订阅者模式,触发watcher来改变虚拟dom中的具体数据

4. 通过更新虚拟dom的元素值,改变最后渲染的dom树的值,完成双向绑定

二、继承:3种:

Function parent(name){

   //属性      this.name = name || ‘parent’;

   //实例方法

   This.sleep = function(){}

}

//原型方法:

Parent.prototype.eat = function(food){

   Console.log(food)

}

1.原型链继承

Function son(){}

Son.prototype = new parent();

Son.prototype.name = ‘son’;

//测试:

Var son = new son();

Console.log(son instanceof parent); //true

Console.log(son instanceof son); //true

2. 构造函数继承

Function son(name){

  Parent.call(this);

  This.name = name || ‘son’;

}

//测试

Var son = new son();

Console.log(son instanceof parent); //true;

Console.log(son instanceof son); //true

3. 组合继承

Function son(name){

   Parent.call(this);

This.name = name || ‘son’

}

Son.prototype = new parent();

//测试

Var son = new son();

Console.log(son instanceof parent); //true;

Console.log(son instanceof son); //true;

4.vue继承:

1. 父组件:

Const component = { template:

父组件

}

子组件继承:extends

Const Comp = Vue.extend(component);

   New Comp({

     El:”#root”,

   Data:{

     Text:”1234”

   }

})

继承的组件的prop需要通过propsData传入,继承的组件排后面

2.子组件:

Const component2 = {

     Extends:component,

     Data(){

      Return {

        Text:1

     }

   }

}

继承的组件改变父组件的东西,可以用$parent,一般不可改变,可以用this.$parent查看

5. Es5继承实现:

(1) Function son(Parent,Child){

Child.prototype = new Parent();

Child.prototype.constructor = Child;//父类构造函数含参时不可用

}

(2)Function son (Parent,CHild){

Child.prototype = Object.create(Parent.prototype);

Child.prototype.constructor = Child;

}

(3) Function son(Parent,Child){

let temp = function(){};

Temp.prototype = Parent.prototype;

Child.prototype = new Temp();

Child.prototype.constructor = Child;

}

6.react继承:

Class Parent extends React.Component{

Constructor(props){

Super(props);

}

}

Class son extends Parent{

Constructor(props){

Super(props);

}

}

三、闭包:闭包就是一级函数调用二级函数,二级函数访问一级函数里的词法作用域里的变量

四、递归:有始有终的循环,使用场景:使用循环ajax请求(我维护的table列表组件,做了一个表头筛选功能,筛选的数据得从后台获取,这个时候需要循环数组发送ajax请求,但ajax是异步的多个请求无法正常返回处理,就用的递归在ajax的回调中重新调用),递归的缺点:如果递归函数的终止条件不明确或者缺少终止条件会导致函数长时间运行,是用户界面处于假死状态。

四、Vue父传子、子传父、非父子传值:

父传子:子组件props创建属性,接收父组件的值

子传父:子组件绑定点击事件,

该事件函数中用$emit触发自定义事件click(){this.$emit(‘abcd’,value)},并传一个参数,

在父组件的子标签中监听该自定义事件并添加该事件的处理方法,  fn:function(value){console.log(value)}

非父子传值:

公共bus :import Vue from ‘vue’; export default new Vue();

A组件:  

import Bus from “./bus.js”    giveValue:function(){Bus.$emit(‘val’,value)}

B组件:

Import Bus from ‘./bus.js’;  Bus.$on(‘val’,data=>{console.log(data)})

五、vue单向数据流、双向数据流:

vue主要由View、Model、ViewModel组成,View和ViewModel不能直接通信

单向数据流:只能从一个方向修改数据,把Model绑定到View,更新Model时View自动更新

双向数据流:由MVVM框架实现,把Model绑定到View的同时View也绑定到Model上,

六、Vue路由守卫:

BeforeEach:导航前置守卫:router.beforeEach((to,from,nect)=>{

To:route:即将进入目标的路由对象;

From:route:当前导航正要离开的路由;

Next:function:next();进行下一个钩子;next(false);终端当前导航;next(‘/’)或next({path:”/”})跳转到不同的地址;next(error)如果传入的参数是一个error实例导航会终止改错误会被传递给router.onErroe()注册过的回调

})

beforeEach:后置守卫

Router.afterEach((to,from)=>{

})

最后是完整的导航解析流程

导航被触发

在失活的组件里调用离开守卫

调用全局的beforeEach守卫

在重用的组件里调用beforeRouteUpdate守卫

在路由配置里调用beforEnter

解析异步路由组件

在被激活的组件里调用beforeRouteEnter

调用全局的beforeResolve守卫

导航被确认

调用全局的afterEach钩子

触发DOM更新

在创建好的实例调用beforeRouteEnter守卫中传给 next 的回调函数

左右tab切换的时候或者权限的时候用路由守卫

五、高阶组件:

个组件包裹着另一个react组件,因为要访问其内部属性,所以要用到继承,高阶组件就是一个函数,接收另一个组件做参数并返回一个新组建。

使代码更具有复用性、逻辑性和抽象特征。

为了代码的复用性、减少代码的冗余

应用场景:

Function Autho(RouterComp){

   Class AuthoHoc extends Component{

      Render(){

         Return

      }

   } return AuthoHoc;

}

五、React组件通信:

父传子:props;

子传父:利用回调函数、利用自定义事件机制

回调函数:

子组件:

父组件:

hideComponent = () => {

    Console.log(‘123’)

}

自定义事件机制

下包:npm install events -s;

src下util建events.js;写:import {EventEmitter} from ‘events’;  export default new EventEmitter();

同级组件1:

Import emitter from ‘./events.js’;

Class list1 extends Component{

     Constructor(props){

         Super(props);

     }

    componentDidMount(){

//组件装在完成后声明一个自定义事件;

      This.eventEmitter = emitter.addListener(‘fn’,(message)=>{

          This.setState({

             message

         })

      })

    Render(){

        Return

{this.state.message}

      }

   }

}

Export default List1;

同级组件2:

Import emitter from ‘./events’;

Class List2 extends Coponent{

    handleClick=(message) =>{

       Emitter.emit(‘fn’,message);

    }

    Render(){

        Return

    }

}

App组件:render(){

     Return

}

跨级组件通信:

·层层组件传递props;

·使用context:

孙组件:

Import React,{Component} from “react”;

Import PropTypes from ‘prop-types’;

Class son extends Component{

//子组件声明自己要是用的context;

      Static contextTpes = {

           Color:PropTypes.string

      }

      Static propTypes = {

           Value:PropTypes.string

      }

      Render(){

            Const {value}  =this.props;

            Return

  • {value}
  •        }

    }

    Export default son;

    子组件:

    Import Son from ‘./son’;

    Class Abcd extends Component{

    //父组件声明自己支持context;

        Static ChildContextTypes = {

            Color:PropTypes.string

        }

        Static propTypes = {

            List:PropTypes.array

        }

    //提供一个函数,用来返回响应的context对象;

        getChildContext(){

            Return {

                Color:”red”

            }

        }

        Render(){

            Const {list} = this.props;

            Return

    {

                List.map((entry,index)=>{

                    

                })

            }

        }

    }

    父组件:

    Import Son from “./son’;

    Const list = [{text:”1”},{text:”2”}];

    Export default class App extends Component{

        Render(){

            Return

        }

    }

    六、React生命周期:

    1、ComponentDidMount();//组件挂载完成之后出发===vue的mounted;

    2、ComponentWillMount();//组件挂载之前===vue的beforeMount;

    3、ComponentWillReceiveProps(nextProps);//组件将要接收新的props;

    componentWillReceiveProps(nextProps){//唯一一个和props相关的生命周期

    //旧的props  this.props;

    //新的props   nextProps;

    }

    4、shouldComponentUpdate(nextProps,nextState);//通过返回值判断组件是否需要更新用于react优化,true更新,false不更新

    shouldComponentUpdate(nextProps,nextState){

    //旧的props;   this.props;

    //新的props;   nextProps;

    //旧的state ;   this.state;

    //新的state;   nextState;

    //返回值Boolean;  默认true;

    }

    5、ComponentWillUPdate//组件将要更新===vue的beforeUPDATE;

    6、ComponentDidUpdate//组件更新完成===vue的updated

    7、ComponentWillUNmount//组件将要卸载;

    8、unmountComponentAtNode()//卸载组件;

    9、三个阶段:


    五、==与===的区别:

    ==:相等:检测两个操作数是否相等

    ===:检测是否严格相等:类型不同就不相等

    六、[endif]Node :

    node搭建http服务器:

    var http = require(‘http’);

    Var fs = require(‘fs’);

    //开启服务

    Var server = http.createServer(function(req,res){

    Var  url = req.url;

    Var file = root + url;

    Fs.readFile(file,function(err,data){

    If(err){

    Res.writeHeader(404,{

    ‘content-type’:’text/html;charset=”utf-8” ’ ;

    })

    Res.write(‘404’);

    Re.end();

    }else{

    Res.wtiteHeader(404,{

    ‘content-type’:”text/html;charset=’utf-8’ ”;

    })

    Res.wirte(data)//讲index.html显示在客户端;

    Res.end();

    }

    })

    }).listen(8080);

    1. Nodejs  npm常用指令:

    Npm  install  -g /-s noduleNames :安装node模块

    Npm  view moduleName:查看

    Npm  list:查看当前目录已下载的包

    Npm  help:查看帮助命令;

    Npm update moduleName:更新模块

    Npm uninstall moduleName:卸载node模块

    Npm  init初始化

    Npm root查看当前包的安装路径

    Npm -v查看npm的版本;

    2.

    七、手动搭建webpack;

    Var webpack = require(‘webpack’);

    Var htmlwebpackPlugin = require(‘html-webpack-plugin’);

    Var root_path = path.reaolve(__dirname);

    Var src_path = path.reoslve(root_path,’src’);

    Var build_path = path.reslove(root_path,’dist’);

    module.exports = {

    Entry:{//入口

            Index:path.resolve(src_path , ’ index.jsx’);

         },

    Output:{//输出

               Path:build_path,

              Filename : ”js/[name].[has:5].js ”//输出文件命名

          },

    Plugins:[//默认配置项

          ],

          Devtool: ”eval-source-map”,

          devServer:{

          historyApiFallback:true,

    Hot:true,//热启动

          Inline:true//

    },

    Reslove:{

          Extensions:[ ‘ .js ’ , ’ .jsx ’ ]

    },

    Module:{

          Loaders:[{

               test:/\.css/,

               Include:[path.resolve(__dirname,’src’)],

               Use:[‘style-loader’ , ’css-loader’]     

          },{

              Test:/\.less/,

              Use:extractTextPlugin.extract({

                     fallback:’style-loader’,

                     use:[‘css-loader’,’less-loader’]

              }),

          },{

              Test:/\.(png | jpg | gif)/,

              Use:[{

                 Loader : ’ file-loader’,

                 Options : {}

              }]

          },{

           Test:/\.(woff | eot | ttf | otf )/,

           Loader:’url-loader’,

          },{

             Test:/\.jsx/,//babel,

             Loader : ’babel-loader’,

          }]

    },

    Plugins:[

    }

    阻止事件冒泡,取消默认事件:

    event.stopPropagation()起到阻止捕获和冒泡阶段中当前事件的进一步传播。使用event.preventDefault()可以取消默认事件。

    先捕获,后冒泡,捕获从上到下,冒泡从下到上

    MVVM:

    原理:深入理解mvvm的原理,实现数据劫持,数据双向绑定,数据驱动页面,数据双向绑定,计算属性computed!

    1.MVVM是什么?

    1.MVVM是Model-View-ViewModel的简写

    2. 它本质上是MVC 的改进版

    3. MVVM(Model-View-ViewModel)框架的由来是MVP(Model-View-Presenter)模式与WPF结合的应用方式时发展演变过来的一种新型架构框架

     2、MVVM优点

    MVVM模式和MVC模式一样,主要目的是分离视图(View)和模型(Model),有几大优点

    1. 低耦合:视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的"View"上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变

    2.可重用性:你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑

    3.独立开发:开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计,使用Expression Blend可以很容易设计界面并生成xml代码

    4. 可测试:界面素来是比较难于测试的,而现在测试可以针对ViewModel来写

    5. 获取元素

    ref 获取dom(refer to缩写)

    findDomNode 获取dom的实例

    按需加载

    封装一个loading组件

    import React from 'react';

    import '../../scss/index.css';

    export default ()=>{

        return

            

        

    }

    react现有版本的生命周期,以及新的生命周期:数据初始化、dom初始化、更新期、销毁期

    2、手机号12345678901变成123****8901;

    '12345678901'.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');

    3、map和forEach的区别:

    map返回新数组原数组不会改变,forEach返回值是undefined你能链式调用,而且forEach没法终止循环

    4、Id排序:var arr6 = [{id:10,age:2},{id:5,age:4},{id:6,age:10},{id:9,age:6},{id:2,age:8},{id:10,age:9}]; arr6.sort(function(a,b){ if(a.id === b.id){//如果id相同,按照age的降序 return b.age - a.age }else{ return a.id - b.id }})console.log(arr6);

    5、发布订阅者模式:class Watch{  store = {}  on(type,fn){  on 订阅   fn为监听者    if(!(this.store[type] instanceOf Array)){          this.store[type] = [];      }      this.store[type].push(fn);   }   emit(type,reset){ emit发布     if(!this.store[type]){        return      }      this.store[type].forEach(item => {        item(reset); 在on的回调函数中将数据返给on      })   }}

    6、js继承:

    1、原型链继承

    核心: 将父类的实例作为子类的原型

    function Cat(){

    }

    Cat.prototype = new Animal();

    Cat.prototype.name = 'cat';

    // Test Code

    var cat = new Cat();

    console.log(cat.name);

    console.log(cat.eat('fish'));

    console.log(cat.sleep());

    console.log(cat instanceof Animal); //true

    console.log(cat instanceof Cat); //true

    特点:

    1. 非常纯粹的继承关系,实例是子类的实例,也是父类的实例

    2.父类新增原型方法/原型属性,子类都能访问到

    3. 简单,易于实现

    缺点:

    1.要想为子类新增属性和方法,必须要在new Animal()这样的语句之后执行,不能放到构造器中

    2. 无法实现多继承

    3.来自原型对象的所有属性被所有实例共享

    4.创建子类实例时,无法向父类构造函数传参

     

    2、构造继承

    核心:使用父类的构造函数来增强子类实例,等于是复制父类的实例属性给子类(没用到原型)

    function Cat(name){

      Animal.call(this);

      this.name = name || 'Tom';

    }

    // Test Code

    var cat = new Cat();

    console.log(cat.name);

    console.log(cat.sleep());

    console.log(cat instanceof Animal); // false

    console.log(cat instanceof Cat); // true

    特点:

    1.解决了1中,子类实例共享父类引用属性的问题

    2.创建子类实例时,可以向父类传递参数

    3.可以实现多继承(call多个父类对象)

    缺点:

    1. 实例并不是父类的实例,只是子类的实例

    2.只能继承父类的实例属性和方法,不能继承原型属性/方法

    3. 无法实现函数复用,每个子类都有父类实例函数的副本,影响性能

    3、实例继承

    核心:为父类实例添加新特性,作为子类实例返回

    function Cat(name){

      var instance = new Animal();

      instance.name = name || 'Tom';

      return instance;

    }

    // Test Code

    var cat = new Cat();

    console.log(cat.name);

    console.log(cat.sleep());

    console.log(cat instanceof Animal); // true

    console.log(cat instanceof Cat); // false

    特点:

    1. 不限制调用方式,不管是new 子类()还是子类(),返回的对象具有相同的效果

    缺点:

    1.实例是父类的实例,不是子类的实例

    2.不支持多继承

    4、拷贝继承

    function Cat(name){

      var animal = new Animal();

      for(var p in animal){

        Cat.prototype[p] = animal[p];

      }

      Cat.prototype.name = name || 'Tom';

    }


    // Test Code

    var cat = new Cat();

    console.log(cat.name);

    console.log(cat.sleep());

    console.log(cat instanceof Animal); // false

    console.log(cat instanceof Cat); // true

    特点:

    1. 支持多继承

    缺点:

    1. 效率较低,内存占用高(因为要拷贝父类的属性)

    2.无法获取父类不可枚举的方法(不可枚举方法,不能使用for in 访问到)

    5、组合继承

    核心:通过调用父类构造,继承父类的属性并保留传参的优点,然后通过将父类实例作为子类原型,实现函数复用

    function Cat(name){

      Animal.call(this);

      this.name = name || 'Tom';

    }

    Cat.prototype = new Animal();Cat.prototype.constructor = Cat;

    // Test Code

    var cat = new Cat();

    console.log(cat.name);

    console.log(cat.sleep());

    console.log(cat instanceof Animal); // true

    console.log(cat instanceof Cat); // true

    特点:

    1.弥补了方式2的缺陷,可以继承实例属性/方法,也可以继承原型属性/方法

    2.既是子类的实例,也是父类的实例

    3.不存在引用属性共享问题

    4. 可传参

    5. 函数可复用

    缺点:

    1.调用了两次父类构造函数,生成了两份实例(子类实例将子类原型上的那份屏蔽了)

    6、寄生组合继承

    核心:通过寄生方式,砍掉父类的实例属性,这样,在调用两次父类的构造的时候,就不会初始化两次实例方法/属性,避免的组合继承的缺点

    function Cat(name){

      Animal.call(this);

      this.name = name || 'Tom';

    }

    (function(){

      // 创建一个没有实例方法的类

      var Super = function(){};

      Super.prototype = Animal.prototype;

      //将实例作为子类的原型

      Cat.prototype = new Super();

    })();

    // Test Code

    var cat = new Cat();

    console.log(cat.name);

    console.log(cat.sleep());

    console.log(cat instanceof Animal); // true

    console.log(cat instanceof Cat); //true 

    Cat.prototype.constructor = Cat; // 需要修复下构造函数

    特点:

    1. 堪称完美

    缺点:

    1. 实现较为复杂

    function Cat(name){

    原因分析:

    关键点:属性查找过程

    执行tom.features.push,首先找tom对象的实例属性(找不到),

    那么去原型对象中找,也就是Animal的实例。发现有,那么就直接在这个对象的

    features属性中插入值。

    在console.log(kissy.features); 的时候。同上,kissy实例上没有,那么去原型上找。

    刚好原型上有,就直接返回,但是注意,这个原型对象中features属性值已经变化了。

    7、setTimeout红任务先执行Promise微任务后执行,js就是红任务,然后就先执行红任务之后把微任务放在红任务队列里继续执行

    8、为什么用虚拟dom更优化:

    采用虚拟DOM的好处是,当数据变化的时候,无需像Backbone那样整体重新渲染,而是局部刷新变化部分

    所谓虚拟DOM,其实就说用JavaScript对象来构建DOM树。

    虚拟DOM以 js结构的形式存在,计算性能会比较好,而且由于减少了实际DOM操作次数,性能会有很大提示。

    虚拟DOM 只是减少了一些情况下, 对真实DOM操作的 次数.

    虚拟DOM只是个JavaScript object

    它会在对比 后再选择更新哪些DOM, 而不会像有些时候, 全部删除再重建.

    获取/修改 大量DOM元素的时候,就会先在虚拟DOM 里 取值 对比.

    9、Apply、call的区别:

    都是改变this指向,作用一样,接受参数不一样;

    func.call(this, arg1, arg2);

    func.apply(this, [arg1, arg2])

    10、React生命周期:

    实例化

    当组件在客户端被实例化,第一次被创建时,以下方法依次被调用:

    1、getDefaultProps2、getInitialState3、componentWillMount4、render5、componentDidMount

    当组件在服务端被实例化,首次被创建时,以下方法依次被调用:

    1、getDefaultProps2、getInitialState3、componentWillMount4、render

    componentDidMount 不会在服务端被渲染的过程中调用。

    getDefaultProps

    对于每个组件实例来讲,这个方法只会调用一次,该组件类的所有后续应用,getDefaultPops 将不会再被调用,其返回的对象可以用于设置默认的 props(properties的缩写) 值。

    var Hello = React.creatClass({

        getDefaultProps: function(){

            return {

                name: 'pomy',

                git: 'dwqs'

            }

        },

        render: function(){

            return (

                

    Hello,{this.props.name},git username is {this.props.dwqs}

            )

        }

    });

    ReactDOM.render(, document.body);

    也可以在挂载组件的时候设置props:

    var data = [{title: 'Hello'}];

    或者调用setProps (一般不需要调用)来设置其 props:

    var data = [{title: 'Hello'}];var Hello = React.render(, document.body);Hello.setProps({data:data});

    但只能在子组件或组件树上调用setProps。别调用 this.setProps 或者 直接修改 this.props。将其当做只读数据

    React通过 propTypes 提供了一种验证props 的方式,propTypes 是一个配置对象,用于定义属性类型:

    var survey = React.createClass({

        propTypes: {

            survey: React.PropTypes.shape({

                id: React.PropTypes.number.isRequired

            }).isRequired,

            onClick: React.PropTypes.func,

            name: React.PropTypes.string,

            score: React.PropTypes.array

            ...

        },

        //...})

    组件初始化时,如果传递的属性和propTypes 不匹配,则会打印一个 console.warn 日志。如果是可选配置,可以去掉.isRequired。常用的 PropTypes 如下:

    getInitialState

    对于组件的每个实例来说,这个方法的调用有且只有一次,用来初始化每个实例的state,在这个方法里,可以访问组件的 props。每一个React组件都有自己的 state,其与 props 的区别在于 state只存在组件的内部,props 在所有实例中共享。

    getInitialState 和 getDefaultPops 的调用是有区别的,getDefaultPops 是对于组件类来说只调用一次,后续该类的应用都不会被调用,而 getInitialState 是对于每个组件实例来讲都会调用,并且只调一次。

    var LikeButton = React.createClass({

      getInitialState: function() {

        return {liked: false};

      },

      handleClick: function(event) {

        this.setState({liked: !this.state.liked});

      },

      render: function() {

        var text = this.state.liked ? 'like' : 'haven\'t liked';

        return (

          

            You {text} this. Click to toggle.

          

        );

      }

    });

    ReactDOM.render(

      ,

      document.getElementById('example')

    );

    每次修改state,都会重新渲染组件,实例化后通过 state 更新组件,会依次调用下列方法:

    1、shouldComponentUpdate2、componentWillUpdate3、render4、componentDidUpdate

    但是不要直接修改this.state,要通过 this.setState 方法来修改。

    componentWillMount

    该方法在首次渲染之前调用,也是再render 方法调用之前修改 state 的最后一次机会。

    render

    该方法会创建一个虚拟DOM,用来表示组件的输出。对于一个组件来讲,render方法是唯一一个必需的方法。render方法需要满足下面几点:

    只能通过this.props 和 this.state 访问数据(不能修改)

    可以返回null,false 或者任何React组件

    只能出现一个顶级组件,不能返回一组元素

    不能改变组件的状态

    不能修改DOM的输出

    render方法返回的结果并不是真正的DOM元素,而是一个虚拟的表现,类似于一个DOM tree的结构的对象。react之所以效率高,就是这个原因。

    componentDidMount

    该方法不会在服务端被渲染的过程中调用。该方法被调用时,已经渲染出真实的DOM,可以再该方法中通过this.getDOMNode() 访问到真实的 DOM(推荐使用 ReactDOM.findDOMNode())。

    var data = [..];var comp = React.createClass({

        render: function(){

            return 

        },

        componentDidMount: function(){

            $(this.getDOMNode()).autoComplete({

                src: data

            })

        }

    })

    由于组件并不是真实的DOM 节点,而是存在于内存之中的一种数据结构,叫做虚拟 DOM (virtual DOM)。只有当它插入文档以后,才会变成真实的 DOM 。有时需要从组件获取真实 DOM 的节点,这时就要用到ref 属性:

    var Area = React.createClass({

        render: function(){

            this.getDOMNode(); //render调用时,组件未挂载,这里将报错

            return 

        },

        componentDidMount: function(){

            var canvas = this.refs.mainCanvas.getDOMNode();

            //这是有效的,可以访问到 Canvas 节点

        }

    })

    需要注意的是,由于this.refs.[refName] 属性获取的是真实 DOM ,所以必须等到虚拟 DOM 插入文档以后,才能使用这个属性,否则会报错。

    存在期

    此时组件已经渲染好并且用户可以与它进行交互,比如鼠标点击,手指点按,或者其它的一些事件,导致应用状态的改变,你将会看到下面的方法依次被调用

    1、componentWillReceiveProps2、shouldComponentUpdate3、componentWillUpdate4、render5、componentDidUpdate

    componentWillReceiveProps

    组件的props 属性可以通过父组件来更改,这时,componentWillReceiveProps 将来被调用。可以在这个方法里更新 state,以触发 render 方法重新渲染组件。

    componentWillReceiveProps: function(nextProps){

        if(nextProps.checked !== undefined){

            this.setState({

                checked: nextProps.checked

            })

        }

    }

    shouldComponentUpdate

    如果你确定组件的props 或者 state 的改变不需要重新渲染,可以通过在这个方法里通过返回false 来阻止组件的重新渲染,返回 `false 则不会执行 render 以及后面的 componentWillUpdate,componentDidUpdate 方法。

    该方法是非必须的,并且大多数情况下没有在开发中使用。

    shouldComponentUpdate: function(nextProps, nextState){

        return this.state.checked === nextState.checked;

        //return false 则不更新组件

    }

    componentWillUpdate

    这个方法和componentWillMount 类似,在组件接收到了新的 props 或者 state 即将进行重新渲染前,componentWillUpdate(object nextProps, object nextState) 会被调用,注意不要在此方面里再去更新props 或者 state。

    componentDidUpdate

    这个方法和componentDidMount 类似,在组件重新被渲染之后,componentDidUpdate(object prevProps, object prevState) 会被调用。可以在这里访问并修改 DOM。

    销毁时

    componentWillUnmount

    每当React使用完一个组件,这个组件必须从 DOM 中卸载后被销毁,此时 componentWillUnmout 会被执行,完成所有的清理和销毁工作,在 componentDidMount 中添加的任务都需要再该方法中撤销,如创建的定时器或事件监听器。

    当再次装载组件时,以下方法会被依次调用:

    1、getInitialState2、componentWillMount3、render4、componentDidMount

    12、Js冒泡排序、快速排序:

    冒泡排序:

      随便从数组中拿一位数和后一位比较,如果是想从小到大排序,那么就把小的那一位放到前面,大的放在后面,简单来说就是交换它们的位置,如此反复的交换位置就可以得到排序的效果。

    function sortA(arr){

        for(var i=0;i

            for(var j=i+1;j

                          //获取第一个值和后一个值比较

                var cur = arr[i];

                if(cur>arr[j]){

                          // 因为需要交换值,所以会把后一个值替换,我们要先保存下来

                    var index = arr[j];

                            // 交换值

                    arr[j] = cur;

                    arr[i] = index;

                }

            }

        }

        return arr;

    }

    快速排序:

       从数组的中间拿一个值,然后通过这个值挨个和数组里面的值进行比较,如果大于的放一边,小于的放一边,然后把这些合并,再进行比较,如此反复即可。

    function sortA(arr){

        // 如果只有一位,就没有必要比较

        if(arr.length<=1){

            return arr;

        }

        // 获取中间值的索引

        var len = Math.floor(arr.length/2);

        // 截取中间值

        var cur = arr.splice(len,1);

        // 小于中间值放这里面

        var left = [];

        // 大于的放着里面

        var right = [];

        for(var i=0;i

            // 判断是否大于

            if(cur>arr[i]){

                left.push(arr[i]);

            }else{

                right.push(arr[i]);

            }

        }

        // 通过递归,上一轮比较好的数组合并,并且再次进行比较。

        return sortA(left).concat(cur,sortA(right));

    }

    13、事件代理:

    事件代理也叫事件委托,多个dom需要添加事件处理时,就用事件代理,

    事件代理是利用事件的冒泡原理来实现的,就是事件从最深的节点开始,然后逐步向上传播事件

    14、微信小程序授权流程:

    第一种使用wx.getUserInfo直接获取微信头像,昵称

    wx.getUserInfo({

         success: function (res) {

          that.setData({

              nickName: res.userInfo.nickName,

             avatarUrl: res.userInfo.avatarUrl,

          })

        },

    })

    能获取到:姓名、性别、手机号、头像

    15、For  for...in for...of的区别:

    普通for循环在Array和Object中都可以使用

    for in在Array和Object中都可以使用。

    for of在Array、Object、Set、Map中都可以使用

    16、json对象和json字符串之间的转化

    json字符串----->json对象

    使用JSON.parse()函数

    var jsonStr = '{"name":"zhangsan","age":23,"email":"[email protected]"}';var json = JSON.parse(jsonStr);

    console.log(json);//输出:Object {name: "zhangsan", age: 23, email: "[email protected]"}

    使用eval()函数

    var jsonStr = '{"name":"zhangsan","age":23,"email":"[email protected]"}';var json = eval ("(" + jsonStr + ")");

    console.log(json);//输出:Object {name: "zhangsan", age: 23, email: "[email protected]"}

    使用jQuery插件jQuery.parseJSON()

    var jsonStr = '{"name":"zhangsan","age":23,"email":"[email protected]"}';var json = jQuery.parseJSON(jsonStr);

    console.log(json);//输出:Object {name: "zhangsan", age: 23, email: "[email protected]"}

    1. json对象------>json字符串

    使用JSON.stringify()

    var json = {name: "zhangsan", age: 23, email: "[email protected]"};

    var jsonStr = JSON.stringify(json);

    console.log(jsonStr);//输出:"{"name":"zhangsan","age":23,"email":"[email protected]"}"

    把数据在前后端之间传递,需要把json对象转换为json字符串

    16、加密

    base64:var bas=new Base64();bas.encode(值);//加密;bas.decode(值)//解密

    Md5: var hash = hex_md5(‘12345’);

    Sha1:

    你可能感兴趣的:(2019-06-04)