2022/6/10

vue中的route和router区别

  • router是VueRouter的一个对象,通过Vue.use(VueRouter)和VueRouter构造函数得到一个router的实例对象,这个对象中是一个全局的对象,他包含了所有的路由包含了许多关键的对象和属性。很多方法在开发过程中都很实用, 例如最常用的有router.push实现路由的切换和跳转, router.replace替换路由
  • route是一个跳转的路由对象,每一个路由都会有一个route对象,是一个局部的对象,可以获取对应的name(当前路径的名字),path(当前路由对象的路径),params(路由中的动态片段和全匹配片段的键值对),query(路由中查询参数的键值对)等, 可以接收路由传递的相关参数

防抖和节流

  • 应用场景: 防抖和节流都是用来防止高频率的js代码的执行

  • 防抖: 理念是如果函数重复高频率触发 => 只触发一次(最后一次)

    //连续触发 => 每一次点击全都会被触发
    $("button").click(function () {
      console.log("准备提交数据");
    });
    
    // 优化1: 普通版 => 利用延时器来设置事件触发到反应的间隔时间
    // 如果在这一次的事件发生之前再次点击,整个延时器被删除,上一个事件就没了,只会发生最后一次
    var timer = null;
    $("button").click(function () {
      clearTimeout(timer); //在这次点击事件触发之前清除之前计时器的干扰
      timer = setTimeout(function () {
        console.log("准备提交数据");
      }, 500);
    });
    
    // 优化2: 闭包版 => 利用匿名函数自执行(页面加载时就执行了),直接得到的返回值是一个函数(点击时调用)
    $("button").click(
      (function () {
        var timer = null;
        return function () {
          clearTimeout(timer);
          timer = setTimeout(function () {
            console.log("准备提交数据");
          }, 300);
        };
      })()
    );
    
    // 优化3: 闭包封装函数版
    var func = debounceFn(function (e) {
      console.log(this);
    }, 1000);
    console.log(func); //得到的func是debounceFn所return的匿名函数
    $("button").click(func);
    
    function debounceFn(callback, delay = 300) {
      //callback是点击后执行的事件 delay是事件延迟的间隔时间(默认为300ms)
      var timer = null;
      return function (...list) {
        // 传入 ...list = 1,2,3,4,5,6,7 => 返回 list = [1, 2, 3, 4, 5, 6, 7]
        // 此时this->事件触发的元素
        clearTimeout(timer);
        var _this = this;
        timer = setTimeout(function () {
          //延时器中this->window => 利用中间变量和apply改变this指向
          callback.apply(_this, list);
        }, delay);
      };
    }
    
  • 节流: 理念是如果函数重复高频率触发 => 降低触发的频率

    // 无优化版 => 无论页面多么细小的滚动都会触发事件
    $(window).scroll(function () {
      console.log("正在滚动");
    });
    
    // 优化1: 基本版 => 设定一个指定的时间差来降低出发的频率
    var start = Date.now(); // 页面加载时的起始时间(ms)
    $(window).scroll(function () {
      var now = Date.now(); // 滚动的当前时间(ms)
      if (now - start >= 300) {
        //只有达到了一定时间触发事件后执行的操作函数才会生效
        console.log("正在滚动");
        start = now; //为下次滚动作准备
      }
    });
    
    // 优化1: 闭包版 => 匿名函数自调用返回一个函数
    $(window).scroll(
      (function () {
        var start = Date.now(); // 页面加载时的起始时间
        return function () {
          var now = Date.now(); // 滚动的当前时间
          if (now - start >= 300) {
            console.log("正在滚动");
            start = now; //为下次滚动作准备
          }
        };
      })()
    );
    
    // 优化2: 闭包函数封装版
    function throttleFn(callback, delay = 300) {
      var start = Date.now(); // 页面加载时的起始时间
      return function (...list) {
        var now = Date.now(); // 滚动的当前时间
        if (now - start >= delay) {
          callback.apply(this, list);
          start = now; //为下次滚动作准备
        }
      };
    }
    $(window).scroll(
      throttleFn(function () {
        console.log("正在滚动");
      }, 1000)
    );
    

判断一个数据是不是数组

1. 数组方法 isArray()
  • 用法: Array.isArray(variable);
  • 这是js的一个方法,专门用来测试对象是否是Array类型
2. instanceof
  • 使用: variable instanceof Array

  • 当 variable 为 Array 的直接或间接子类,或者是其接口的实现类,结果result 都返回 true,否则返回false。

  • var obj = {a:1}
    var arr = [1,2,3]
    obj instanceof Array  // fasle
    arr instanceof Array  // true
    
3. 构造函数constructor
  • 使用: variable. _proto_ .constructor.name
[1,2,3].__proto__.constructor.name  //'Array'
4. Prototype + tostring + call
  • 使用: Object.prototype.toString.call(variable).indexOf('Array') !== -1;
Object.prototype.toString.call([1,2,3]).indexOf('Array') //8
Object.prototype.toString.call({a:1,b:2}).indexOf('Array') //-1

typeof和instanceof的区别

  • typeof会返回一个变量的基本类型,instanceof返回的是一个布尔值
  • instanceof 可以准确地判断复杂引用数据类型,但是不能正确判断基础数据类型
  • typeof 也存在弊端,它虽然可以判断基础数据类型(null 除外),但是引用数据类型中,除了function 类型以外,其他的也无法判断
typeof "111" //string
[1,2,3] instanceof Array  //true

Redux遵循的三个原则

1、 单一事实来源:整个应用的状态存储在单个 store 中的对象/状态树里。单一状态树可以更容易地跟踪随时间的变化,并调试或检查应用程序。

2、 状态是只读的:改变状态的唯一方法是去触发一个动作。动作是描述变化的普通 JS 对象。就像 state 是数据的最小表示一样,该操作是对数据更改的最小表示。

3、 使用纯函数进行更改:为了指定状态树如何通过操作进行转换,你需要纯函数。纯函数是那些返回值仅取决于其参数值的函数。

vue组件中生命周期的调用顺序

1、 组件的调用顺序都是先父后子,渲染完成的顺序是先子后父

2、 组件的销毁操作是先父后子,销毁完成的顺序是先子后父

加载渲染过程

父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount- >子mounted->父mounted

子组件更新过程

父beforeUpdate->子beforeUpdate->子updated->父updated

父组件更新过程

父 beforeUpdate -> 父 updated

销毁过程

父beforeDestroy->子beforeDestroy->子destroyed->父destroyed

react中什么是受控组件和非控组件

(1)受控组件 在使用表单来收集用户输入时,例如<input><select><textearea>等元素都要绑定一个change事件,当表单的状态发生变化,就会触发onChange事件,更新组件的state。这种组件在React中被称为受控组件,在受控组件中,组件渲染出的状态与它的value或checked属性相对应,react通过这种方式消除了组件的局部状态,使整个状态可控。react官方推荐使用受控表单组件。

受控组件更新state的流程:

  • 可以通过初始state中设置表单的默认值
  • 每当表单的值发生变化时,调用onChange事件处理器
  • 事件处理器通过事件对象e拿到改变后的状态,并更新组件的state
  • 一旦通过setState方法更新state,就会触发视图的重新渲染,完成表单组件的更新

受控组件缺陷: 表单元素的值都是由React组件进行管理,当有多个输入框,或者多个这种组件时,如果想同时获取到全部的值就必须每个都要编写事件处理函数,这会让代码看着很臃肿,所以为了解决这种情况,出现了非受控组件。

(2)非受控组件 如果一个表单组件没有value props(单选和复选按钮对应的是checked props)时,就可以称为非受控组件。在非受控组件中,可以使用一个ref来从DOM获得表单值。而不是为每个状态更新编写一个事件处理程序。

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.handleSubmit = this.handleSubmit.bind(this);
  }
  handleSubmit(event) {
    alert('A name was submitted: ' + this.input.value);
    event.preventDefault();
  }
  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" ref={(input) => this.input = input} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}


React官方的解释:

要编写一个非受控组件,而不是为每个状态更新都编写数据处理函数,你可以使用 ref来从 DOM 节点中获取表单数据。 因为非受控组件将真实数据储存在 DOM 节点中,所以在使用非受控组件时,有时候反而更容易同时集成 React 和非 React 代码。如果你不介意代码美观性,并且希望快速编写代码,使用非受控组件往往可以减少你的代码量。否则,你应该使用受控组件。

总结: 页面中所有输入类的DOM如果是现用现取的称为非受控组件,而通过setState将输入的值维护到了state中,需要时再从state中取出,这里的数据就受到了state的控制,称为受控组件

posted @ 2022-06-11 00:43  嘻嘻不是菜鸟了  阅读(17)  评论(0编辑  收藏  举报