在Vue中异步请求传递到子组件props中出现_ob_:Observer导致访问不到值

在Vue中异步请求传递到子组件props中出现_ob_:Observer

引言:有时候,当我们在父组件中调用异步请求去请求数据的并把请求到的数据传递给子组件的props时,

会发现子组件中拿不到值,没有响应,watch也监视不到,使用深度(deep)立即(immediate)监

视(watch)也只是得到一个不可遍历的_ob_:Observer

看如下代码:

父组件
<template>
  <div>
    <Page :pageData="pageData" @pageClick="pageClick" ref="child"></Page>
  </div>
</template>
<script>
	data(){
		return{
			pageData: {},
		};
	}
	methods:{
		 /**
         * 获取记录
         */
        weekLog(currentPage) {
          let tmpObj = ...;
		
		  //看如下代码
          this.log.weekLog(tmpObj).then((res) => {
            this.initPageData(res);
          });
        },

        /**
         * 初始化pageData
         */
        initPageData(res) {
          // let a = {};
          // a.totalPages = res.data.pageNum;
          // a.currentPage = this.currentPage;
          // a.pagerCount = this.pagerCount ? this.pagerCount : 7;
          // this.pageData = a;
          // this.$set(this.pageData, "totalPages", res.data.pageNum);
          // this.$set(this.pageData, "currentPage", this.currentPage);
          // this.$set(this.pageData, "pagerCount", 7);
          this.pageData.totalPages = res.data.pageNum;
          this.pageData.currentPage = this.currentPage;
          this.pageData.pagerCount = this.pagerCount ? this.pagerCount : 7;
          console.log(this.pageData.totalPages);
        },
	}
<script>
子组件:
<template>
  <div class="page">
  </div>
</template>

<script>
import { Pagination } from "@/api/extendsion/pages/index.js";
export default {
  props: {
    pageData: {
      type: Object,
      required: true,
      default: function () {
        return null;
      },
    },
  },
  watch: {
    pageData: {
      handler(newVal, oldVal) {
        console.log(newVal, oldVal);	//_ob_:Observer undefined 
        console.log(this.pageData.totalPages);	//undefined
      },
      deep: true,
      immediate: true,
    },
  },
};
</script>

当weekLog请求成功后,调用initPageData方法将值传递到了pageData中,同时也传递到了子组件的pageData中(理论上),但是在子组件中打印却出现_ob_:Observer undefined在watch中,因为这里并没有在HTML标签内使用模版语法以及其他响应式操作,而是由pageData的改变去调用某些函数,所以没有使用生命周期钩子),pageData值改变,watch也监视不了,点开可以看到值,但是如果去访问的话访问不了,都是undefined,如下:

image-20230413104047455

尝试的网上的一些方法,比如说:

  • JSON.parse(JSON.stringify(值))
  • Object.assign({},this.owner)

以上两种方法都没什么用,也有可能是对我来说没什么用img

认为异步导致错误

一开始以为是异步导致数据传递的问题,网上查了一些关于_ob_:Observer的资料,都说是数据还没赋值给变量,就开始访问了,导致访问不到

就比如,在我的代码中,当weekLog异步请求之后,将请求到的值赋给了pageData,值还没有传递到子组件中,就访问子组件props的pageData,因为Vue更新是异步的,所以不排除有这种可能。

然后,我又尝试了一下两种方法:

  • 第一种:调用子组件的方法

    • 我在子组件中声明一个方法,每次请求并赋值完后,调用一下,不就可以访问到了

    • weekLog(currentPage, pageCount) {
        this.log.weekLog(tmpObj).then((res) => {
          this.initPageData(res)
          this.$refs.child.childInit();
        });
      },
      
    • 第一种方法的确有用,但是违背了组件的独立性(个人认为),不可能每次调用的时候,都在一个异步回调中调用一个指定的方法

  • 第二种:setTimeOut

    • 使用定时器,在一定时间后访问,这个也可以访问到,但是不确定因素太多了,比如说:异步请求的时间,网络等等之类的。

实例创建之后添加属性

之后,我发现根本问题并不在异步,而是数据根本就没有进行传递,也就是pageData并不是一个响应式数据,导致watch监视不到,这是为什么呢?

收集资料后发现,我在父组件中定义pageData为空对象

pageData:{}

之后的方法initPageData实则是为pageData添加了三个属性

官方文档定义:如果在实例创建之后添加新的属性到实例上,它不会触发视图更新

image-20230413112221909

这个对象内并没有为三个属性添加getter和setter,只有这两个控制器存在时,才能触发响应式更新

解决方法:

  • 一开始就声明好属性,如下:

    • pageData:{
      	currentPage:0,
      	pagerCount:0,
      	totalPages:0,
      }
      
  • 添加属性时使用Vue.$set

    • this.$set(this.pageData, "totalPages", res.data.pageNum);
      this.$set(this.pageData, "currentPage", 7);
      this.$set(this.pageData, "pagerCount", 1);
      
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

命中不缺狗——

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值