web前端知识---------------3

Vue的响应式原理


什么是响应式,也即是说,数据发生改变的时候,视图会重新渲染,匹配更新为最新的值。
Object.defineProperty 为对象中的每一个属性设置 get 和 set 方法,每个声明的属性,都会有一个 专属的依赖收集器 subs,当页面使用到 某个属性时,触发 ObjectdefineProperty - get函数,页面的 watcher 就会被 放到 属性的依赖收集器 subs 中,在 数据变化时,通知更新;
当数据改变的时候,会触发Object.defineProperty - set函数,数据会遍历自己的 依赖收集器 subs,逐个通知 watcher,视图开始更新;

Vue3.x响应式数据原理


Vue3.x改用Proxy替代Object.defineProperty。
因为Proxy可以直接监听对象和数组的变化,并且有多达13种拦截方法。并且作为新标准将受到浏览器厂商重点持续的性能优化。
Proxy只会代理对象的第一层,Vue3是怎样处理这个问题的呢?
判断当前Reflect.get的返回值是否为Object,如果是则再通过reactive方法做代理, 这样就实现了深度观测。
监测数组的时候可能触发多次get/set,那么如何防止触发多次呢?我们可以判断key是否为当前被代理对象target自身属性,也可以判断旧值与新值是否相等,只有满足以上两个条件之一时,才有可能执行trigger。
 

Vue3.0 里为什么要用 Proxy API替代 defineProperty API?


1.defineProperty API 的局限性最大原因是它只能针对单例属性做监听。
Vue2.x中的响应式实现正是基于defineProperty中的descriptor,对 data 中的属性做了遍历 + 递归,为每个属性设置了 getter、setter。这也就是为什么 Vue 只能对 data 中预定义过的属性做出响应的原因。
2.Proxy API的监听是针对一个对象的,那么对这个对象的所有操作会进入监听操作, 这就完全可以代理所有属性,将会带来很大的性能提升和更优的代码。
Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。
3.响应式是惰性的。
在 Vue.js 2.x 中,对于一个深层属性嵌套的对象,要劫持它内部深层次的变化,就需要递归遍历这个对象,执行 Object.defineProperty 把每一层对象数据都变成响应式的,这无疑会有很大的性能消耗。
在 Vue.js 3.0 中,使用 Proxy API 并不能监听到对象内部深层次的属性变化,因此它的处理方式是在 getter 中去递归响应式,这样的好处是真正访问到的内部属性才会变成响应式,简单的可以说是按需实现响应式,减少性能消耗。

Proxy 与 Object.defineProperty 优劣对比


1.Proxy 可以直接监听对象而非属性;
2.Proxy 可以直接监听数组的变化;
3.Proxy 有多达 13 种拦截方法,不限于 apply、ownKeys、deleteProperty、has 等等是 Object.defineProperty 不具备的;
4.Proxy 返回的是一个新对象,我们可以只操作新的对象达到目的,而 Object.defineProperty 只能遍历对象属性直接修改;
5.Proxy 作为新标准将受到浏览器厂商重点持续的性能优化,也就是传说中的新标准的性能红利;
6.Object.defineProperty 的优势如下:
兼容性好,支持 IE9,而 Proxy 的存在浏览器兼容性问题,而且无法用 polyfill 磨平,因此 Vue 的作者才声明需要等到下个大版本( 3.0 )才能用 Proxy 重写。

vue中组件的data为什么是一个函数?而new Vue 实例里,data 可以直接是一个对象


我们知道,Vue组件其实就是一个Vue实例。

JS中的实例是通过构造函数来创建的,每个构造函数可以new出很多个实例,那么每个实例都会继承原型上的方法或属性。

Vue的data数据其实是Vue原型上的属性,数据存在于内存当中。Vue为了保证每个实例上的data数据的独立性,规定了必须使用函数,而不是对象。

因为使用对象的话,每个实例(组件)上使用的data数据是相互影响的,这当然就不是我们想要的了。对象是对于内存地址的引用,直接定义个对象的话组件之间都会使用这个对象,这样会造成组件之间数据相互影响。

使用函数后,使用的是data()函数,data()函数中的this指向的是当前实例本身,就不会相互影响了。

而 new Vue 的实例,是不会被复用的,因此不存在引用对象的问题。
 

vue中data的属性可以和methods中方法同名吗,为什么?


可以同名,methods的方法名会被data的属性覆盖;调试台也会出现报错信息,但是不影响执行;
原因:源码定义的initState函数内部执行的顺序:props>methods>data>computed>watch

vue中created与mounted区别


在created阶段,实例已经被初始化,但是还没有挂载至el上,所以我们无法获取到对应的节点,但是此时我们是可以获取到vue中data与methods中的数据的;
在mounted阶段,vue的template成功挂载在$el中,此时一个完整的页面已经能够显示在浏览器中,所以在这个阶段,可以调用节点了;

Vue中computed与method的区别


相同点:
如果作为模板的数据显示,二者能实现响应的功能,唯一不同的是methods定义的方法需要执行
不同点:
1.computed 会基于响应数据缓存,methods不会缓存;
2.diff之前先看data里的数据是否发生变化,如果没有变化computed的方法不会执行,但methods里的方法会执行
3.computed是属性调用,而methods是函数调用

虚拟DOM中key的作用


简单的说:key是虚拟DOM对象的标识,在更新显示时key起着极其重要的作用。
复杂的说:当状态中的数据发生了变化时,react会根据【新数据】生成【新的虚拟DOM】,随后React进行【新虚拟DOM】与【旧虚拟DOM】的diff比较,比较规则如下:

旧虚拟DOM中找到了与新虚拟DOM相同的key
1.若虚拟DOM中的内容没有变,直接使用之前的真是DOM
2.若虚拟DOM中内容变了,则生成新的真实DOM,随后替换掉页面中之前的真实DOM
旧虚拟DOM中未找到与新虚拟DOM相同的key:根据数据创建新的真实DOM,随后渲染到页面

用index作为key可能会引发的问题


若对数据进行:逆序添加/逆序删除等破坏顺序的操作,会产生没有必要的真实DOM更新,界面效果虽然没有问题,但是数据过多的话,会效率过低;
如果结构中还包含输入类的DOM,会产生错误DOM更新,界面有问题;
注意!如果不存在对数据的逆序操作,仅用于渲染表用于展示,使用index作为key是没有问题的。

Vue中watch用法详解


在vue中,使用watch来监听数据的变化;
1.监听的数据后面可以写成对象形式,包含handler方法,immediate和deep。
2.immediate表示在watch中首次绑定的时候,是否执行handler,值为true则表示在watch中声明的时候,就立即执行handler方法,值为false,则和一般使用watch一样,在数据发生变化的时候才执行handler。
3.当需要监听一个对象的改变时,普通的watch方法无法监听到对象内部属性的改变,只有data中的数据才能够监听到变化,此时就需要deep属性对对象进行深度监听
 

vue中对mixins的理解和使用


mixins是一种分发 Vue 组件中可复用功能的非常灵活的方式。混合对象可以包含任意组件选项。当组件使用混合对象时,所有混合对象的选项将被混入该组件本身的选项。
而mixins引入组件之后,则是将组件内部的内容如data等方法、method等属性与父组件相应内容进行合并。相当于在引入后,父组件的各种属性方法都被扩充了。
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值