Vue 关于生命周期、$nextTick、网络请求、DOM渲染之间的存在的问题(分享)

问题一

为什么在 created 中使用了 $nextTick 可以通过 Vue 的方式获取 DOM???

  • 首先说一下为什么我会有这个疑问
  • 在事件循环(Event loop)中,微任务的优先级是要大于 DOM 渲染的
  • 而在 Vue 底层对于 $nextTick 的实现,如果浏览器支持 Promise,那么就是用的 Promise
  • Promise.then 也是微任务
  • 我这里测试是使用的谷歌浏览器,所以 $nextTick === 微任务
<div id="app" ref="app">
  <span>{{count}}</span>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
  new Vue({
    el: "#app",
    data: {
      count: 1
    },
    created() {
      // 这里可以很明显的看到是有的
      this.$nextTick(() => {
        console.dir(this.$refs.app); // div#app
      })
    },
  })
</script>
  • 对于 nextTick,Vue 官网是这样解释的:
  • 将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。
  • 看到这里我恍然大悟,vue 的数据变更是放入异步队列进行的更改,然后使用 nextTick 是最后入队,这样就可以在前面队列更新完成后获取到最新的
<div id="app" ref="app">
  <span>{{count}}</span>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
  new Vue({
    el: "#app",
    data: {
      count: 1
    },
    created() {
      // 这里 DOM 其实早就渲染好了,只是 Vue 在之后的生命周期中又对页面的 DOM 进行了更改
      // 也就是经过 Vue 渲染的 DOM 才能使用 this.$refs 的方法去获取
      
      // 因为 Vue 是数据驱动页面,而我们通过原生的方法在 created 中进行获取,
      // 很有可能在后面的生命周期又对 DOM 进行了更改,所以最好不要这样去做
      console.dir(document.querySelector("#app")); // div#app
      console.dir(this.$refs.app); // undefined
    },
  })
</script>

问题二

  • 刚才上面说到了,使用 $nextTick 获取的 DOM,是货真价实经过 Vue 更新 DOM
  • 起初我也是这样想的😂,但是前一段时间做项目遇到了一个问题,搞了好久,大概需求就是我有一个 DOM 默认没有高度,它的高度是网络请求的数据来撑开的,然后我在 mounted 生命周期中使用 $nextTick 就是获取不到更新后的 DOM
  • 其实这里还是一个时机问题,首先 $nextTick 是微任务,然后网络请求时宏任务
  • 网络请求成功之后,才会对数据进行更改,才会再次更新 DOM
mounted() {
  fetch("xxx")
    .then(res => {
      console.log("data");
    })
  this.$nextTick(() => {
    console.log(1111);
  })
},
// 1111
// "data"
// 先执行的 111,在执行的网络请求
// 因为数据是在请求之后进行的修改,DOM 也是数据更改之后才会更新的,所以那就拿不到最新的 DOM 了
// 这里想要拿到最新的 DOM,要在 updated 中去获取
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值