使用this.$nextTick()获取不到数据更新后的this.$refs.xxx.及场景分析

 更新时间:2023年02月06日 09:46:17   作者:Rised  
今天遇到了这样一个场景,在数据更新之后,使用this.$nextTick(()=>{console.log(this.$refs.xxx)}) 获取不到改dom,但是用setTimeout能够获取到,在此记录一下,感兴趣的朋友跟随小编一起看看吧

使用this.$nextTick()获取不到数据更新后的this.$refs.xxx.

今天遇到了这样一个场景,在数据更新之后,使用this.$nextTick(()=>{console.log(this.$refs.xxx)}) 获取不到改dom,但是用setTimeout能够获取到,在此记录一下。

先看代码

  
<!--这是模板代码,父级用的v-else-if,与父级同级的还有两个盒子,分别用v-if和v-else控制着-->
<div ref="articleContent" class="right" v-html="articles.content"></div>
 
 
 
//这是script代码
 
 mounted() {
    
        this.getArticlesDetail()
    
  },
  methods: {
   async getArticlesDetail(){
        try {
            
            const {data}= await getArticlesDetail(this.articleId);
            /* vue数据更新是异步的 ,在这一步数据加载出来,但是组件还没没有渲染出来,因为在组件中有个v-if判断,在数据加载出来之后,才能渲染出来组件*/
            /* console.log(this.$refs.articleContent) */
            /* 所以要放在定时器是异步执行,试了用this.$nextTick,不行 */
          /*  */
            this.articles = data
            /* 只能用setitmeout是因为数据在在下个Event Loop中也出不来,这是因为v-if中的条件在下次事件循环中也不一定能够满足。但是setTimeout的执行时机是没有办法确定前边的任务到底需要多长时间执行完 */
              this.$nextTick(() => {
                console.log(this.$refs.articleContent)
            });
            console.log(data)
        } catch (error) {
            if(error.response && error.response.status===404){
                this.errStatus=404;
                this.$toast('服务器错误')
            }
            console.log(error)
            this.$toast('请求失败,请稍后再试')
        }
        /* 无论成功失败都要调用loading为false,关闭它 */
        this.loading=false
    }
  },

 这是控制台打印的效果.

 获取不到.

vue官网中对于vue.nextTick()中的解释:

 也就是说在下个事件循环中没有满足v-if中的条件,所以没有获取到数据。

在vue 中的devtools中 可以获取到。

然后我们修改成setTimeout

  
<!--这是模板代码,父级用的v-else-if,与父级同级的还有两个盒子,分别用v-if和v-else控制着-->
<div ref="articleContent" class="right" v-html="articles.content"></div>
 
 
 
//这是script代码
 
 mounted() {
    
        this.getArticlesDetail()
    
  },
  methods: {
   async getArticlesDetail(){
        try {
            
            const {data}= await getArticlesDetail(this.articleId);
            /* vue数据更新是异步的 ,在这一步数据加载出来,但是组件还没没有渲染出来,因为在组件中有个v-if判断,在数据加载出来之后,才能渲染出来组件*/
            /* console.log(this.$refs.articleContent) */
            /* 所以要放在定时器是异步执行,试了用this.$nextTick,不行 */
          /*  */
            this.articles = data
            /* 只能用setitmeout是因为数据在在下个Event Loop中也出不来,这是因为v-if中的条件在下次事件循环中也不一定能够满足。但是setTimeout的执行时机是没有办法确定前边的任务到底需要多长时间执行完 */
              setTimeout(() => {
                console.log(this.$refs.articleContent)
            });
            console.log(data)
        } catch (error) {
            if(error.response && error.response.status===404){
                this.errStatus=404;
                this.$toast('服务器错误')
            }
            console.log(error)
            this.$toast('请求失败,请稍后再试')
        }
        /* 无论成功失败都要调用loading为false,关闭它 */
        this.loading=false
    }
  },

这是控制台打印的效果

 可以看出来有效果.

在vue中的devtools中也有,

这是为什么呢? 

只能用setitmeout是因为数据在在下个Event Loop中也出不来,这是因为v-if中的条件在下次事件循环中也不一定能够满足。但是setTimeout的执行时机是没有办法确定前边的任务到底需要多长时间执行完,所以使用setTimeout会更好。

补充:详解Vue中this.$nextTick()用法

语法:

this.$nextTick( [ callback ] )

用法: 

 this.$nextTick将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。它跟全局方法 Vue.nextTick 一样,不同的是回调的 this 自动绑定到调用它的实例上,等同于updated生命周期函数

updated用法:由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。

示例: 

下面讲解一个点击按钮是输入框聚焦的示例:

<template>
  <div>
      <input ref="myInp" type="text" placeholder="这是一个输入框" v-if="isShow">
      <button v-else @click="btn">点击我进行搜索</button>
  </div>
</template>
 
<script>
 
// 获取到输入框
// 输入框调用事件方法focus()达到聚焦行为
export default {
    data(){
        return {
            isShow: false
        }
    },
    methods: {
        btn(){
            this.isShow = true;
 
            this.$refs.myInp.focus(); // 没有效果
            
            // 原因: data变化更新DOM是异步的
            // 输入框还没有挂载到真实DOM上
            // 解决:
            // this.$nextTick(() => {
            //     this.$refs.myInp.focus()
            // })
        }
        //async btn(){  
        //    this.isShow = true;
        //    
        //    // 扩展: await取代回调函数
        //    // $nextTick()原地返回Promise对象
        //    await this.$nextTick()
        //    this.$refs.myInp.focus()
        //}
    },
     //扩展
    updated(){  
     // this.$refs.myInp.focus()
    
    }
}
</script>

 直接在methods获取DOM调用聚焦方法是没有效果的,更改之后的文本是需要 dom 更新之后才会实现的,就像我们把将要打印输出的代码放在 setTimeout(fn, 0) 中,这时候用this.$nextTick就能合理解决此问题,如果我们想进页面就处于聚焦状态的话就可以使用updated生命周期函数,调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作

到此这篇关于使用this.$nextTick()获取不到数据更新后的this.$refs.xxx.及场景分析的文章就介绍到这了,更多相关this.$nextTick()获取不到数据内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • vue路由跳转后刷新指定页面的方法

    vue路由跳转后刷新指定页面的方法

    这篇文章主要介绍了vue路由跳转后刷新指定页面的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-12-12
  • 在vue中使用echarts的方法以及可能遇到的问题

    在vue中使用echarts的方法以及可能遇到的问题

    Echarts是一个与框架无关的JS图表库,但是它基于Js,这样很多框架都能使用它,下面这篇文章主要给大家介绍了关于在vue中使用echarts的方法以及可能遇到的问题的相关资料,需要的朋友可以参考下
    2022-09-09
  • Vue如何解决子组件data从props中无法动态更新数据问题

    Vue如何解决子组件data从props中无法动态更新数据问题

    这篇文章主要介绍了Vue如何解决子组件data从props中无法动态更新数据问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-10-10
  • Vue路由的懒加载深入详解

    Vue路由的懒加载深入详解

    这篇文章主要介绍了vue-router路由懒加载及实现方式,路由懒加载的主要作用是将 路由对应的组件打包成一个个的js代码块,只有在这个路由被访问到的时候,才会加载对应组件的代码块,需要的朋友可以参考下
    2022-12-12
  • 安装vue-cli的简易过程

    安装vue-cli的简易过程

    安装vue-cli的前提是你已经安装了npm,安装npm你可以直接下载node的安装包进行安装。接下来通过本文给大家介绍安装vue-cli的简易过程,感兴趣的朋友跟随脚本之家小编一起学习吧
    2018-05-05
  • 浅谈Vue开发人员的7个最好的VSCode扩展

    浅谈Vue开发人员的7个最好的VSCode扩展

    这篇文章主要介绍了浅谈Vue开发人员的7个最好的VSCode扩展,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • vue2中如何自定义组件的v-model

    vue2中如何自定义组件的v-model

    这篇文章主要介绍了vue2中如何自定义组件的v-model,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08
  • Vue移动端下拉刷新组件的使用教程

    Vue移动端下拉刷新组件的使用教程

    这篇文章主要介绍了Vue移动端下拉刷新组件的使用教程,每一次我在使用vant组件库里面list组件和下拉刷新连在一起用的时候都会出现下拉刷新和列表下滑局部滚动的冲突,这就很难受,这篇文章将解决它
    2023-04-04
  • vue项目中做编辑功能传递数据时遇到问题的解决方法

    vue项目中做编辑功能传递数据时遇到问题的解决方法

    这篇文章主要介绍了vue项目中做编辑功能传递数据时遇到问题的解决方法,vue父组件向子组件传递数据的问题,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-12-12
  • 对vue2.0中.vue文件页面跳转之.$router.push的用法详解

    对vue2.0中.vue文件页面跳转之.$router.push的用法详解

    今天小编就为大家分享一篇对vue2.0中.vue文件页面跳转之.$router.push的用法详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-08-08

最新评论