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的控制,称为受控组件