this.$nextTick() 解释为在下次DOM更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的DOM. 也就是说,当dom元素发生改变,重新渲染dom树后,再执行vue.$nextTick()里面的内容。
其实用方法一般为 this.$nextTick( ()=>{} ), 为了不影响this指向,一般为箭头函数。
案例一
点击修改dom元素按钮,使字体变红,背景变蓝(设置为两次修改dom元素)
<template> <div> <div :id="myid" class="" ref="str">123456789</div> <button @click="changeColor()">修改dom元素</button> </div></template><script> export default { data() { return { myid:'' }; }, methods: { changeColor(){ this.myid = 'color' if (this.$refs.str.id == 'color') { this.$refs.str.className = 'background' } } } }</script><style scoped> #color{color:red;} .background{background: green;}</style>
点击事件发生时,id属性值发生改变,改为color, 字符串变红,这个时候dom元素进行更新,但是条件判断并不是等到更新结束后才执行,判断结果为false,不会执行第二次修改dom元素。
(只有第一次修改dom元素,dom更新结束之后,条件判断结果才为true)
案例一未使用 this.$nextTick() 结果演示:
第一次点击事件后只有字体颜色改变。(第二次点击背景颜色才改变)
将第二次修改dom元素放入 this.$nextTick() 中:
methods: { changeColor(){ this.myid = 'color' this.$nextTick( () =>{ if (this.$refs.str.id == 'color') { this.$refs.str.className = 'background' } }) } }
案例一使用 this.$nextTick()后 结果演示:
点击事件后,两个修改dom元素都得到更新 (第一次字体变红,第二次背景为绿)
案例二
点击编辑,按照理来讲,应该自动获取焦点出现光标。
<template> <div> <!-- :disabled='isDisabled'最初设置禁止输入属性 --> <input ref="inputTitle" type="text" value='' :disabled='isDisabled' placeholder="请输入内容"> <button @click="getedit()">编辑</button> </div></template><script> export default { data() { return { isDisabled:true, }; }, methods: { getedit(){ this.isDisabled = false this.$refs.inputTitle.focus() //获取焦点 } } }</script><style scoped> div{ height: 40px; width:260px; background: gray; } input{ margin:10px 10px 10px 10px ; }</style>
input输入框 必须得先设置为可编辑状态,才可以获取焦点, 但是我执行 this.isDisabled=false后,并不会等到dom元素更新结束,就会执行 ...focus()来获取焦点,因为设置为可编辑状态还未结束,所以一定获取不到焦点
案例二未使用 this.$nextTick() 结果演示:
点击编辑 ,并不会获取到焦点出现光标。
将获取焦点放入 this.$nextTick() 中:
methods: { getedit(){ this.isDisabled = false this.$nextTick(function(){ this.$refs.inputTitle.focus() //获取焦点}) } }
案例二使用 this.$nextTick()后 结果演示:
点击编辑,获取焦点。
案例三
首先要明白,vue声明周期函数中,在created阶段vue实例已经创建,但是还不能获取DOM元素。所以在这个阶段要修改dom元素,一般都是要放在this.$nextTick()中。
案例:
在created阶段将vue实例中input标签的value属性更改为苹果 ,因为要等到dom树更新渲染完成之后,所以要用this.$nextTick() 否则控制台会报错(啥啥啥 is not definded in 啥啥啥 ...)
<template> <div><input ref="str" type="text" :value="string"></div></template><script> export default { data() { return { string:'苹果', }; }, created() { this.$nextTick(()=>{ this.$refs.str.value = '西瓜' } ) }, mounted(){ console.log(this.$refs.str.value); } }</script>
演示结果:
当dom元素更新后 控制台已经打印了苹果,之后执行this.$nextTick()里面的内容。
...其实,用定时器也可以实现:
created() { setTimeout(()=>{ this.$refs.str.value = '西瓜' },10) },
定时器时间哪怕设置为0,也是异步加载,也没关系。