VUE父组件异步获取数据,子组件接收的值为空的问题

 更新时间:2023年10月24日 15:31:26   作者:修复BUG中  
这篇文章主要介绍了VUE父组件异步获取数据,子组件接收的值为空的问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

在vue中引用Echarts图表,动态渲染数据时一直不展示数据。

父组件异步请求获取数据传给子组件,子组件接收的打印的真实的值却为初始值,如下所示

  • 父组件

  • 子组件

原因的话:

加载渲染的时候,请求是一个异步的操作,子组件在拿到数据前就渲染了,子组件没有监控到值得变化

父子组件加载渲染过程

父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted

昨天晚上遇到这个问题,在网上找了是下面三个方法:

  • 在子组件用watch监控父组件传递过来值得变化,设置deep:true【deep官方定义:为了发现对象内部值的变化,可以在选项参数中指定 deep: true。注意监听数组的变更不需要这么做。】
  • 在父组件使用v-if,当请求结束之后,改变v-if内变量的值,加载子组件
  • 使用vuex全局状态管理,这个没尝试

上面三种方法的话:

  • 第一种是最简洁明了的,但是昨天晚上第一种方法一直不成功,可能是语法写错了,今天早上上班试了一下才成功;
  • 因为我们做的是数据展示,所以第二种就不适合我们的需求;
  • 第三种的话我就没试,网上的解决流程感觉太麻烦了;

这样的话,其实昨天就没解决这个问题,下班回去的时候换了一个思路想了这个问题,这个原因就是父组件异步请求没有更新子组件的数据值,其实我们可以手动的更新子组件的值,在父组件异步请求拿到数据时,在成功回调赋值的时候,手动的调用子组件的方法,并把数据当成参数传递过去,子组件的处理就是在该方法内手动的刷新对象的,今天早上上班按照该思路,发现可以解决这个问题。

下面就介绍一下vue父组件异步获取数据,子组件接收的值为空三种解决方法:

1.父组件异步获取数据,调用子组件方法重新赋值 【第二种方法不行,推荐使用该方法】

  • 父组件
<template>
  <div class="index">
  	//设置ref的值,下面调用
    <ChartBasicLine :chartObj="chartRegUser" :ref="chartRegUser.type" />
  </div>
</template>

<script>
import { getStatUser } from '@/api/data'
import ChartBasicLine from '@/components/Chart/ChartBasicLine'

export default {
  components: {
    ChartBasicLine
  },
  data() {
    return {
      chartRegUser: {
        num: 0,
        percent: '0.00%',
        status: 0,
        type: 'reg_user',
        tips: '新增用户',
        title: '新增用户(NU)',
        link: '',
        isShow: false,
        xData: [],
        yData: []
      }
    }
  },
  created() {
    this.getStatUser()
  },
  methods: {
    getStatUser() {
      const _this = this
      
      // 异步请求获取数据
      getStatUser().then(res => {
        if (res.code === 0) {

		  // 赋值
          _this.$set(_this.chartRegUser, 'xData', res.data['x_data'])
          _this.$set(_this.chartRegUser, 'yData', res.data['y_data'])
		  
		  // 这里是调用子组件的refresh的方法
          _this.$refs[_this.chartRegUser.type].refresh(res.data)
        }
      })
    }
  }
}
</script>
  • 子组件
<template>
  <div class="ChartBasicLine">
    <div
      :ref="chartObj.type"
      class="chart_show"
    />
  </div>
</template>

<script>
export default {
  name: 'ChartBasicLine',
  props: {
    chartObj: {
      type: Object
    }
  },
  data() {
    return {
      option: {
        tooltip: {
          trigger: 'axis'
        },
        grid: {
          top: '22px',
          left: '40px',
          right: '30px'
        },
        xAxis: {
          type: 'category'
        },
        yAxis: {
          type: 'value'
        },
        series: [{
          type: 'line'
        }]
      },
      myChart: {}
    }
  },
  mounted() {
    this.showChart()
  },
  methods: {
    showChart() {
      this.myChart = this.$echarts.init(this.$refs[this.chartObj.type])
      this.option.xAxis['data'] = this.chartObj.xData
      this.option.series[0]['data'] = this.chartObj.yData
      this.myChart.setOption(this.option)
    },
    /**
     * 父组件给图表信息重新赋值,并重新刷新图表
     */
    refresh(data) {
      this.option.xAxis['data'] = data['x_data']
      this.option.series[0]['data'] = data['y_data']
      this.myChart.setOption(this.option)
    }
  }
}
</script>
<style>
  .ChartBasicLine .el-input {
    margin-right: 0 !important;
  }
</style>

2.子组件内使用watch监控对象值变化时重新赋值【推荐】

  • 子组件
<template>
  <div class="ChartBasicLine">
    <div
      :ref="chartObj.type"
      class="chart_show"
    />
  </div>
</template>

<script>
export default {
  name: 'ChartBasicLine',
  props: {
    chartObj: {
      type: Object
    }
  },
  data() {
    return {
      option: {
        tooltip: {
          trigger: 'axis'
        },
        grid: {
          top: '22px',
          left: '40px',
          right: '30px'
        },
        xAxis: {
          type: 'category'
        },
        yAxis: {
          type: 'value'
        },
        series: [{
          type: 'line'
        }]
      },
      myChart: {}
    }
  },
  watch: {
    chartObj: { // 监控该变量,重新赋值并刷新图表
      handler(newVal, oldVal) {
        this.chartObj = newVal
        this.showChart()
      },
      deep: true // 必须设置
    }
  },
  mounted() {
    this.showChart()
  },
  methods: {
    showChart() {
      this.myChart = this.$echarts.init(this.$refs[this.chartObj.type])
      this.option.xAxis['data'] = this.chartObj.xData
      this.option.series[0]['data'] = this.chartObj.yData
      this.myChart.setOption(this.option)
    }
  }
}
</script>

3.父组件内使用v-if渲染子组件【不推荐】

  • 父组件
<template>
  <div class="index">
  	// 通过v-if来控制子组件显示
    <ChartBasicLine v-if="isShow" />
  </div>
</template>

<script>
import { getStatUser } from '@/api/data'
import ChartBasicLine from '@/components/Chart/ChartBasicLine'

export default {
  components: {
    ChartBasicLine
  },
  data() {
    return {
      chartRegUser: {
        num: 0,
        percent: '0.00%',
        status: 0,
        type: 'reg_user',
        tips: '新增用户',
        title: '新增用户(NU)',
        link: '',
        isShow: false,
        xData: [],
        yData: []
      },
      isShow: false // 控制子组件是否展示
    }
  },
  created() {
    this.getStatUser()
  },
  methods: {
    getStatUser() {
      const _this = this
      getStatUser().then(res => {
        if (res.code === 0) {
          _this.$set(_this.chartRegUser, 'xData', res.data['x_data'])
          _this.$set(_this.chartRegUser, 'yData', res.data['y_data'])
          
          // 异步请求获取数据,展示子组件
          _this.isShow = true
        }
      })
    }
  }
}
</script>

VUE中数组赋空值注意事项

在js或者Vue中,给数组赋空值不可以直接赋空值,例如:

var list = {a:'12',b:'34'};// 创建一个数组

list = [];// 数组赋空值

否则会在再次赋值的时候报错

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • vue2.0 可折叠列表 v-for循环展示的实例

    vue2.0 可折叠列表 v-for循环展示的实例

    今天小编大家分享一篇vue2.0 可折叠列表 v-for循环展示的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-09-09
  • vue+elemet实现表格手动合并行列

    vue+elemet实现表格手动合并行列

    这篇文章主要为大家详细介绍了vue+elemet实现表格手动合并行列,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • vue计算属性及使用详解

    vue计算属性及使用详解

    计算属性就是模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。这篇文章主要介绍了vue计算属性详解,需要的朋友可以参考下
    2018-04-04
  • Vuejs 2.0 子组件访问/调用父组件的方法(示例代码)

    Vuejs 2.0 子组件访问/调用父组件的方法(示例代码)

    这篇文章主要介绍了Vuejs 2.0 子组件访问/调用父组件的方法(示例代码),需要的朋友可以参考下
    2018-02-02
  • Vue封装svg-icon组件使用教程

    Vue封装svg-icon组件使用教程

    SVG(Scalable Vector Graphics)可缩放矢量图形,是一种用于描述基于二维的矢量图形的 XML 标记语言,其基本矢量显示对象包括矩形、圆、椭圆、多边形、直线、任意曲线等,还能显示文字对象和嵌入式外部图像
    2023-02-02
  • vue 关闭浏览器窗口的时候,清空localStorage的数据示例

    vue 关闭浏览器窗口的时候,清空localStorage的数据示例

    今天小编就为大家分享一篇vue 关闭浏览器窗口的时候,清空localStorage的数据示例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-11-11
  • electron-builder打包vue2项目问题总结

    electron-builder打包vue2项目问题总结

    这篇文章主要介绍了electron-builder打包vue2项目问题总结,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2024-08-08
  • 用Vue封装导航栏组件

    用Vue封装导航栏组件

    这篇文章主要为大家详细介绍了用Vue封装导航栏组件的方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • Vue封装组件并上传到npm的教程详解

    Vue封装组件并上传到npm的教程详解

    这篇文章主要为大家详细介绍了Vue封装组件并上传到npm的相关教程,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以参考下
    2024-04-04
  • Vue3实现瀑布流的2种核心方案

    Vue3实现瀑布流的2种核心方案

    这篇文章主要介绍了Vue3中实现瀑布流的两种主要方案:CSS原生方案和JS计算方案,CSS方案适用于静态短列表,而JS方案适用于长列表和复杂布局,能够保证排序正常并支持懒加载,文章详细介绍了两种方案的实现步骤,需要的朋友可以参考下
    2025-12-12

最新评论