沃梦达 / IT编程 / 前端开发 / 正文

vue父子组件传值不能实时更新的解决方法

Vue是一个以数据驱动、组件化的前端框架,其中组件化是Vue中较为重要的概念之一,组件之间的通信则成为Vue中较为普遍的需求,下面这篇文章主要给大家介绍了关于vue父子组件传值不能实时更新的解决方法,需要的朋友可以参考下

最近做项目,遇到个大坑,这会爬出来了,写个总结,避免下次掉坑。

vue父子组件传值不能实时更新问题,父组件将值传给了子组件,但子组件显示的值还是原来的初始值,并没有实时更新,为什么会出现这种问题呢?

出现这个问题,可能有以下两个原因:

一、 父组件没有把值传过去,子组件没有获取到最新的值。

二、子组件接收到最新的值了,但是没有实时渲染到视图上。

如果是第一种情况很简单,核对传的参数,确保把最新的值传过去就可以了。

若是第二种情况,稍微有些麻烦,但也可以解决,主要有两种解决方案:

① 利用v-if的重新渲染机制,获取到值之后,将子组件重新渲染一遍。

② 利用watch监听数据,若是数据变化,调用视图渲染方法。

下面,结合项目的实际情况,具体分析这两种方法。

在项目中,将erchart中的生成仪表盘的数据封装了一个子组件,父组件中传给仪表盘一个初始值,后续,调用后台接口返回最新的数据传给这个仪表盘组件的之后,发现仪表盘中的数据并没有实时的更新。仪表盘如下图:

IiBzcmM9

 首先,利用第①种方法,利用v-if渲染机制

设置一个参数reRender。设置v-if=“reRender”,并将reRender初始值设置为false,从后台获取数据之后,将reRender=true。

这样就能够将最新的数据渲染到子组件的视图中了。但这样,如果我在同一个页面中调用了很多次这个子组件,生成多个仪表盘,就需要设置很多个类似于reRender的属性。

那么有的小可爱就提出来了,我设置一个reRender属性,然后几个子组件共用这个属性不就可以了吗,几个后台接口调完更新数据之后在统一将reRender=true。

这种方法,我尝试过了,不可以,我不知道原因。

只有将reRender=true放在那个调接口的方法里,获取到后台数据之后,才可以。尝试了网上提出的强制更新的方法,也不行。

所以,遇到这种一个页面调用多个这种组件的情况,使用v-if就很繁琐。

若是,别人封装了这么一个组件,数据更新的时候还要利用v-if重新渲染一下,那就感觉这个组件可能封装的不是太好,所以,咱们还是完善子组件。

这里就涉及到了第二种方法,设置watch监听,监听数据,当子组件监听到数据发生改变时,调用方法。

监听传的数据,这里面用到了两个属性immediate和deep,在watch中,不会监听初始值,只有当值改变时才会执行handler函数。但是,我们想要在最初赋值的时候,也执行handler函数,就需要用到immediate:true。而普通监听只能监听字符串、数字等值,要想监听到对象中某个属性的变化,就需要用到深度监听deep:true

IiBzcmM9

 在这之后,我发现控制台报错了, ”TypeError: Cannot read property ‘getAttribute’ of undefined”,如下所示:

IiBzcmM9

 后面查了一些资料是因为:在vue中,数据和dom渲染是异步的,当dom还没渲染,却用数据去赋值的话,就会出现这个问题。解决方法是:利用this.$nextTick()。this.$nextTick()将数据渲染方法放到dom渲染之后,这样就不会出现这个问题了。

IiBzcmM9

 依此,子组件数据就可以实时更新了。如下图:

IiBzcmM9

总结

到此这篇关于vue父子组件传值不能实时更新的解决方法的文章就介绍到这了,更多相关vue父子组件传值不实时更新内容请搜索编程学习网以前的文章希望大家以后多多支持编程学习网!

本文标题为:vue父子组件传值不能实时更新的解决方法