温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Vue nextTick如何获取更新后的DOM的实现

发布时间:2022-01-25 10:44:17 来源:亿速云 阅读:315 作者:kk 栏目:开发技术

这篇文章将为大家详细讲解有关Vue nextTick如何获取更新后的DOM的实现,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

前两天在开发时遇到一个需求:打开对话框的时候自动聚焦其中的输入框。由于原生的 autofocus 属性不起作用,需要使用组件库提供的 focus 方法手动手动获取焦点。于是有如下代码:

<el-button @click="openDialog">点击打开 Dialog</el-button>

<el-dialog :visible.sync="dialogVisible">
  <el-input v-model="input" ref="input"></el-input>
</el-dialog>
methods: {
  openDialog() {
    this.dialogVisible = true;
    const input = this.$refs.input;
    input.focus();
  },
},

结果报错了,原因是没有获取到 input 组件;通过 log,也验证了 this.$refs.input 的值确实是 undefined。但是经过测试,如果对话框默认状态是打开的,就不会报错;明明组件就在那,为什么获取不到呢?

生命周期 update

经过分析,这种现象是由于 Vue 实例的更新机制造成的。从下方的生命周期图(局部)中可以看出,组件装载好之后,遇到数据变化时将重新渲染虚拟 DOM(可以理解为 HTML 中的组件节点)。在本例中,隐藏的 Dialog 组件(以及其中的 input 组件)本来并没有渲染在 DOM 中,是在观察到 dialogVisible 属性变为 true 后再进行更新渲染的。

Vue nextTick如何获取更新后的DOM的实现

而网页渲染通常是一个异步任务,因此在 visible 属性刚刚更改时(一个函数中是同步过程),DOM 渲染还没有进行,因此自然获取不到此时还不存在的 input 组件了。

关于异步、JS任务队列、宏任务与微任务等概念的更多介绍,可参考博文JS多线程:任务队列

为了更直观地展示这个过程,可以在更新前后的钩子函数中试图获取组件并进行打印:

beforeUpdate() {
  console.log("beforeUpdate");
  const input = this.$refs.input;
  console.log(input);
},
updated() {
  console.log("updated");
  const input = this.$refs.input;
  console.log(input);
},
methods: {
  openDialog() {
    this.dialogVisible = true;
    console.log("click open");
  },
},

结果如下,可以验证之前的分析和猜想:

click open
beforeUpdate
undefined
updated
VueComponent {...}

Vue.nextTick

为了解决这个问题,Vue 提供了全局 api Vue.nextTick(),它的作用是提供下次 DOM 更新之后的回调。也就是说,在更新数据后调用 api,就能够获取到重新渲染后的 DOM 并进行相关操作。

nextTick 方法可以广泛适用于各种需要在数据更新后对相关 DOM 进行操作的情景,例如 v-if 、watch 等。

在上文的例子中再加入 nextTick:

openDialog() {
  this.dialogVisible = true;
  console.log("click open");
  this.$nextTick(function () {
    console.log("next tick");
    const input = this.$refs.input;
    console.log(input);
    input.focus();
  });
},

可以看到,回调确实是在 DOM 更新之后,也就是 updated 执行之后才执行的。获取组件与手动获得焦点的操作也能够正确执行了。

click open
beforeUpdate
undefined
updated
VueComponent {...}
next tick
VueComponent {...}

Promise

如果没有提供回调参数,并且浏览器支持 Promise,调用 nextTick 将返回一个 Promise。也就是说下面几种写法是等价的(环境支持的情况下):

Vue.nextTick(function () {...})
Vue.nextTick(() => {...})

Vue.nextTick().then(function () {...})
Vue.nextTick().then(() => {...})

Vue的优点

Vue具体轻量级框架、简单易学、双向数据绑定、组件化、数据和结构的分离、虚拟DOM、运行速度快等优势,Vue中页面使用的是局部刷新,不用每次跳转页面都要请求所有数据和dom,可以大大提升访问速度和用户体验。

关于Vue nextTick如何获取更新后的DOM的实现就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI