vue.nextTick 是 Vue 官方给我们提供的一个 API(方法), 作用是在下次 DOM 更新循环结束之后执行延迟回调. 在修改数据之后立即使用这个方法, 获取更新后的 DOM;
那么我们的理解是: 当数据发生变化之后, DOM 视图并不会立即更新, 如果我们在发生变化之后立马去获取某个节点或者某个节点的值, 很有可能结果就是 undefined; 因为 Vue 实现响应式并不是数据发生变化之后 DOM 立即变化, 而是按一定的策略进行 DOM 的更新;
来看一个小 demo:
App.vue
- <template>
- <div id="app">
- <div ref="message">{{msg}}</div>
- <div v-if="msg1">{{msg1}}</div>
- <button @click="changeMsg">Change the Message</button>
- </div>
- </template>
- <script>
- export default {
- name: 'App',
- data(){
- return {
- msg:"Hello Vue",
- msg1: '',
- }
- },
- methods:{
- changeMsg(){
- this.msg='hello world';
- this.msg1=this.$refs.message.innerhtml;
- console.log("更新 DOM 之前:"+this.msg1)
- }
- }
- }
- </script>
- <style>
- #App {
- font-family: 'Avenir', Helvetica, Arial, sans-serif;
- -webkit-font-smoothing: antialiased;
- -moz-OS X-font-smoothing: grayscale;
- text-align: center;
- color: #2c3e50;
- margin-top: 60px;
- }
- </style>
我们通过运行代码能够看到当我们不在 this.$nextTick 方法里面进行 DOM 操作的时候, this.$refs.message.innerHTML 的值存储的还是之前的初始值;
修改代码:
App.vue
- <template>
- <div id="app">
- <div ref="message">{{msg}}</div>
- <div v-if="msg1">{{msg1}}</div>
- <button @click="changeMsg">Change the Message</button>
- </div>
- </template>
- <script>
- export default {
- name: 'App',
- data(){
- return {
- msg:"Hello Vue",
- msg1: '',
- }
- },
- methods:{
- changeMsg(){
- this.msg='hello world';
- // this.msg1=this.$refs.message.innerHTML;
- // console.log("更新 DOM 之前:"+this.msg1)
- this.$nextTick(()=>{
- this.msg1=this.$refs.message.innerHTML;
- console.log("更新 DOM 之后:"+this.msg1)
- })
- }
- }
- }
- </script>
- <style>
- #App {
- font-family: 'Avenir', Helvetica, Arial, sans-serif;
- -webkit-font-smoothing: antialiased;
- -moz-OS X-font-smoothing: grayscale;
- text-align: center;
- color: #2c3e50;
- margin-top: 60px;
- }
- </style>
修改代码之后我们可以发现, 使用 this.$nextTick 很容易的就接收到了更新后的值, 正如官网解释: 在下次 DOM 更新循环结束之后执行延迟回调. 在修改数据之后立即使用这个方法, 获取更新后的 DOM;
再来修改代码对比一下:
App.vue
- <template>
- <div id="app">
- <div ref="message">{{msg}}</div>
- <div v-if="msg1">{{msg1}}</div>
- <button @click="changeMsg">Change the Message</button>
- </div>
- </template>
- <script>
- export default {
- name: 'App',
- data(){
- return {
- msg:"Hello Vue",
- msg1: '',
- }
- },
- methods:{
- changeMsg(){
- this.msg='hello world';
- this.msg1=this.$refs.message.innerHTML;
- console.log("更新 DOM 之前:"+this.msg1)
- this.$nextTick(()=>{
- this.msg1=this.$refs.message.innerHTML;
- console.log("更新 DOM 之后:"+this.msg1)
- })
- }
- }
- }
- </script>
- <style>
- #App {
- font-family: 'Avenir', Helvetica, Arial, sans-serif;
- -webkit-font-smoothing: antialiased;
- -moz-OS X-font-smoothing: grayscale;
- text-align: center;
- color: #2c3e50;
- margin-top: 60px;
- }
- </style>
经过修改代码, 我们现在可以很容易看出来 this.$nextTick(callback) 的作用, callback 是回调函数也就是我们要进行操作 DOM 的事情;
应用场景:
在 vue 的生命周期钩子函数 created() 中进行 DOM 操作的时候一定要把 DOM 操作放入到 this.$nextTick() 中;
因为在 created 钩子函数触发的时候, DOM 是没有进行渲染的; DOM 没有进行渲染, 然后进行 DOM 操作无疑是徒劳的;
所以我们在 created 中进行 DOM 操作的时候, 一定要将 DOM 操作放入到 this.$nextTick() 中;
与之相反的是 mounted, 因为当触发 mounted 的时候, DOM 的挂载和渲染都已经完成了, 所以在 mounted 中进行 DOM 操作是不会有任何问题的;
因为 DOM 更新是异步的, 像 v-if 指令判断增删 DOM 元素, 我们在方法中给变量赋值的时候, 如果不使用 this.$nextTick(), 我们很有可能拿到的还是初始值, 如果想拿到更新后的值, 需要使用 this.$nextTick() 方法
来源: https://www.cnblogs.com/dengyao-blogs/p/11630195.html