Vue底层理解

1. key的作用

首先v-for

列表渲染时,我们可以用v-for基于一个数组来渲染一个列表。v-for指令需要使用item in arr形式的特殊语法来进行渲染列表,arr是源数据,

<ul id="example-1">
  <li v-for="item in arr" :key="item.id">
    {{ item.message }}
  </li>
</ul>

当Vue正在使用v-for渲染元素列表的时候,它默认的是使用**就地更新**的策略。如果数据项的顺序被改变,Vue将不会移动DOM元素来匹配数据项的顺序,而是采用了就地更新每个元素,并且确保他们在每个索引的位置正确渲染。

这个默认的模式是高效的,但是只是适用于不依赖子组件状态来临时DOM的状态的列表渲染输出。

为了能够更高效的渲染页面,你需要为每项提供一个唯一的key值。

这边提醒您,渲染时尽量提供id作为key值。

为什么?

我想到的是当数组发生删除,插入变化时,下标将会重组。因该是这样可见。

vue中为什么不建议你使用数组下标作为 key值呢_yunchong_zhao的博客-CSDN博客

key值特殊的属性主要使用在Vue的虚拟DOM算法,在新旧node对比时辨识VNodes,如果不使用keyVue会使用一种最大限度减少动态元素,并且尽可能的尝试就地复用,相同类型元素的算法,而使用key值时,它会就与key的变化重新排列元素顺序,并且会移出key不存在的元素

vue中为什么不建议你使用数组下标作为 key值呢_yunchong_zhao的博客-CSDN博客

Vue中key值的作用_理小理...的博客-CSDN博客_vue中的key值的作用

key值的作用

在大多数情况下使用在循环语句中,从本质来有两点:

1、主要是用在vue的虚拟Dom算法,在新旧nodes对比时辨识VNodes,相当于唯一标识ID,

2、vue会尽可能的高效的渲染元素,通常恢复已有的元素而不是从头开始进行渲染,因此使用key值可以提高渲染效率,同理,改变某一个元素的key值会使该元素重新被渲染。

2.nextTick的实现原理

  this.$nextTick(() => {
          for (var i = 0; i < this.$refs.tree.store._getAllNodes().length; i++) {
            undefined
            this.$refs.tree.store._getAllNodes()[i].expanded = false
          }
        })

 nextTick作用:在下次DOM更新循环结束之后执行的延迟回调

1.vue是异步渲染,$nextTick会待Dom渲染完之后调用

2.页面渲染时会将data的修改做整合,多次data修改只会渲染一次

2.汇总data的修改,一次性更新试图

3.减少DOM操作次数,提高性能

首先nextTick并不是浏览器本身提供的一个异步API,而是Vue中,用过由浏览器本身提供的原生异步API封装而成的一个异步封装方法。

它对于浏览器异步API的选用规则如下,Promise存在取由Promise.then,不存在Promise则取MutationObserver,MutationObserver不存在setImmediate,setImmediate不存在最后取setTimeout来实现。

nextTick即有可能是微任务,也有可能是宏任务,从优先去Promise和MutationObserver可以看出nextTick优先微任务,其次是setImmediate和setTimeout宏任务。

同步代码执行完毕之后,优先执行微任务,其次才会执行宏任务

setTimeout(() => {
      console.log("settimeout 1");
    }, 0);
    console.log("同步 1");
    Promise.resolve().then(() => {
      console.log("promise 1");
    });
    this.$nextTick(() => {
      console.log("nexttick");
    });
    Promise.resolve().then(() => {
      console.log("promise 2");
    });
    console.log("同步 2");
    setTimeout(() => {
      console.log("settimeout 2");
    }, 0);

实现一个nextTick


 public myNextTick(callback: Function) {
    return Promise.resolve().then(() => {
      callback();
    });

 3.Vue 响应式原理

 

Observer : 它的作用是给对象的属性添加 getter 和 setter,用于依赖收集和派发更新

用于收集当前响应式对象的依赖关系,每个响应式对象包括子对象都拥有一个 Dep 实例(里面 subs 是 Watcher 实例数组),当数据有变更时,会通过 dep.notify()通知各个 watcher。

Watcher : 观察者对象 , 实例分为渲染 watcher (render watcher),计算属性 watcher (computed watcher),侦听器 watcher(user watcher)三种

Watcher 和 Dep 的关系

watcher 中实例化了 dep 并向 dep.subs 中添加了订阅者,dep 通过 notify 遍历了 dep.subs 通知每个 watcher 更新。

4.为什么在 Vue3.0 采用了 Proxy,抛弃了 Object.defineProperty?

Object.defineProperty 本身有一定的监控到数组下标变化的能力,但是在 Vue 中,从性能/体验的性价比考虑,尤大大就弃用了这个特性(Vue 为什么不能检测数组变动 )。为了解决这个问题,经过 vue 内部处理后可以使用以下几种方法来监听数组

Object.defineProperty 只能劫持对象的属性,因此我们需要对每个对象的每个属性进行遍历。Vue 2.x 里,是通过 递归 + 遍历 data 对象来实现对数据的监控的,如果属性值也是对象那么需要深度遍历,显然如果能劫持一个完整的对象是才是更好的选择。

Proxy 可以劫持整个对象,并返回一个新的对象。Proxy 不仅可以代理对象,还可以代理数组。还可以代理动态增加的属性。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值