大国工匠普拉斯金 2022-04-06 05:51 采纳率: 75%
浏览 64
已结题

Vue中的nextTick的一个问题


<template>
  <div>
    <div ref="list" v-for="(num, index) in abc" :key="index">{{ num }}</div>
    <button @click="clickFN">点我</button>
  </div>
</template>

<script>
export default {
  name: 'App',

  data() {
    return { abc: [+new Date()] }
  },

  methods: {
    clickFN() {
      this.abc.push(+new Date())
      const list = this.$refs.list
      console.log(list, list.length)
    }
  }
}
</script>

<style lang="css" scoped></style>


js的同步异步我知道,vue的dom是异步操作知道,
我想点击按钮的时候,abc数组push最新的时间戳,然后在控制台打印,this.$refs.list.length,但是打印出来每次的length都少一个数

img


我也会用nextTick来解决这个问题。
我的疑问是:nexttick根据vue官方的解释是,"在下一次 DOM 更新结束后执行其指定的回调",但是页面上已经有新的标签元素了啊,标签元素不也是dom的一部分吗?为什么不使用nexttick的情况下,拿到的length和页面上的元素总数不同呢?我卡在这里了。我自己认为,点击了按钮之后,abc已经push了新数据了,而且新数据产生的标签元素,已经在页面上呈现出来了不是吗?那么为什么拿到的length确实缺少的呢?

  • 写回答

4条回答 默认 最新

  • 归来巨星 前端领域新星创作者 2022-04-06 10:04
    关注

    数据渲染是数据渲染,dom渲染是dom渲染

    简单的说就像 created 与 mounted的区别一样,一个是数据挂载,一个是视图渲染

    既然有两个生命周期 就很明显的知道 数据挂载的时机与视图渲染的时机是不同的,这样相当于是最简单的理解

    包括一系列的监听,很简单的道理 script 与 template 两者其实你可以认为是没有任何关系的,可以推荐你去理解一下vue的观察者模式 也叫做发布订阅者模式

    当一个数据变更时,并不是会立刻将视图进行更新

    img

    看下图层的 逻辑关系

    this.xxx变更时 通知object.defineProperty 通知 Dep、Wather等进行中转,这一步只是实现数据的变更,所以说你可以抓到最新的数据,也就是说你在 this.abc.push(+new Date()) 下方抓到的是最新的数据,当然这里面并不是做了简单的最新数据处理,更下一步是要根据diff比对,实现数据图形的最小量更新,这个时候你直接去用ref抓数据,其实只是抓到的上一层视图的数据,因为并没有还没有对视图进行更新

    那么在视图更新完成之后 vue对外暴露出 $nextTick钩子,你可以在这个钩子中抓到最新的dom结构 所以逻辑大概就是这样一个逻辑

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 4月15日
  • 已采纳回答 4月7日
  • 创建了问题 4月6日

悬赏问题

  • ¥15 opencv 无法读取视频
  • ¥15 用matlab 实现通信仿真
  • ¥15 按键修改电子时钟,C51单片机
  • ¥60 Java中实现如何实现张量类,并用于图像处理(不运用其他科学计算库和图像处理库))
  • ¥20 5037端口被adb自己占了
  • ¥15 python:excel数据写入多个对应word文档
  • ¥60 全一数分解素因子和素数循环节位数
  • ¥15 ffmpeg如何安装到虚拟环境
  • ¥188 寻找能做王者评分提取的
  • ¥15 matlab用simulink求解一个二阶微分方程,要求截图