在我们用vue时,我们经常用到一个方法是this.$nextTick,相信你也用过,我常用的场景是在进行获取数据后,需要对新视图进行下一步操作或者其他操作时,发现获取不到dom,这篇文章主要给大家介绍了关于$nextTick的相关资料,需要的朋友可以参考下
1.功能描述
今天我们要实现这个一个小功能;页面渲染完成后展示一个div元素;当点击这个div元素后;div元素消失;出现一个input元素;并且input元素聚焦,想必大家觉得简单,我们一起来看看~
创建一个组件,组件名称NextTick.vue;
在页面中引入注册
2.父组件
<div> </div>
3.子组件NextTick.vue
<div> <div>我是组件</div><div class="sun">显示input</div></div>
4为什么是undefined
this.flag=false; this.$refs.inputRef.focus();
当执行页面操作的时候,this.$refs.inputRef.focus();
是需要消耗时间的(还没有还得及刷新;还是旧的页面)
此时还没有获取到dom元素。
所以会报错。
解决方式1:
因此只要让页面能够获取元素就行;使用setTimeout
setTimeout(()=>{ this.$refs.inputRef.focus(); },100)
这样来处理这个问题,是可以的;
但是显得非常的不专业;
解决方式2:
//当组件根据最新的data数据,重新在视图上完成渲染后,在执行里面的函调函数 this.$nextTick(()=>{ this.$refs.inputRef.focus(); })
5.将v-if更本文来源gaodai#ma#com搞*!代#%^码网5改为v-show可以获取焦点吗?
有人说:因为v-if是动态创建和销毁;在创建和销毁的过程中,是需要时间的!所以才会使用v-if获取不到元素节点,用v-show就可以避免。
感觉说的有点道理?
我们尝试一下将v-if换成v-show
<div> <div>我是组件</div><div class="sun">显示input</div></div>
6.实际结果
我们发现虽然是页面没有报错,但是还没有聚焦;改为v-show明显也不能够解决这个问题
之所以会出现这个问题,是因为子组件中将this.flag=false后,立刻去执行了下面的代码
this.$refs.inputRef.focus();
而在执行的时候,视图还没没有来得及刷新;还是旧的页面,此时还不能够获取到dom元素,因此出现了undefined;也就是为什么我们加上延时后就可以聚焦了;
当组件根据最新的data数据,重新在视图上完成渲染后,在执行里面的函调函数
这就是$nextTick的基本用法
this.$nextTick(()=>{ this.$refs.inputRef.focus(); })
7.将组件变成页面可以获取焦点吗?
又有人说:因为是子组件,子组件比父组件后渲染。所以没有获取到元素节点。
这也是理由….
感觉还没有上一个小伙伴说的对,为了解决疑惑。我们决定将子组件变成页面在看看
<div> <div>我是组件</div><div class="sun">显示input</div></div>
我们发现仍然不可以;这就充分说明了:更新data的数据后,vue并不是实时更新的。
数据更新到显示到页面有时间差,我们在时间差内调用页面数据,当然获取不到。
也就是说:Vue在更新 DOM 时是异步执行的
8.为什么会有$nextTick
之所以会有$nextTick;因为在vue中数据发生变化后;视图上的dom并不会立刻去跟新;dom的跟新是需要时间的
下面我们通过一个小实验来看一下
<div> <div> <h1>{{ cont }}</h1></div><div class="sun">改变值</div></div>
我们发现,第一次的值和第二次的值,是不一样的;因为视图上dom的跟新是需要之间的;我们在这个之间差内去获取元素值;仍然是旧值;所以第一次的值是最初的值;第二次的值才是改变
以上就是让你一看就明白的$nextTick讲解的详细内容,更多请关注gaodaima搞代码网其它相关文章!