面试题——父组件数据异步更新子组件如何知道?

69 阅读1分钟

看下面代码,为什么父组件更新了而子组件的created打印没有更新?

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png" />
    <h1>这是父组件的num:{{num}}</h1>
    <Count :num="num" />
  </div>
</template>

<script>
import Count from "./homeView-components/Count.vue"
export default {
  name: "HomeView",
  components: {Count},
  data() {
    return {
      num: 11,
    };
  },
  mounted() {
    setTimeout(() => {
      this.num = 222;
    },2000)
  },
};
</script>

父组件我为了方便模拟异步数据,设计了一个定时器,让他两秒后更新数据

<template>
    <div>
        <h2>这是子组件的num:{{num}}</h2>
    </div>
</template>

<script>
export default {
    props:["num"],

    created() {
        console.log(this.num)
    },
   
}
</script>

然后我们再看一下浏览器

image.png

可以看到当父组件更新了,虽然子组件也更新了,但是created依旧是没有打印变化。

这里是因为生命周期的问题,当父组件运行到子组件的时候会马上进行子组件生命周期的更新,但是created是组件创建完成后,所以它只会执行一次,所以也就是打印一次。

我们再看看下面代码有什么问题

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png" />
    <h1>这是父组件</h1>
    <h1>**********************************</h1>
    <h1>这是子组件</h1>
    <Count :my-arr="myArr" />
  </div>
</template>

<script>
import Count from "./homeView-components/Count.vue"
export default {
  name: "HomeView",
  components: {Count},
  data() {
    return {
      myArr:""
    };
  },
  mounted() {
    setTimeout(() => {
      this.myArr = {"datenum":[10,20,30]};
      console.log("父组件对象更新完毕");
    },2000)
  },
};
</script>

父组件我们可以通过传一个对象过去。

<template>
    <div>
        <h2>这是子组件:{{myArr.datenum[1]}}</h2>
    </div>
</template>

<script>
export default {
    props:["myArr"],

    created() {
        console.log(this.myArr)
    },
   
}
</script>

然后我们看一下浏览器

image.png

可以看到子组件更新了数据,created报了一个空值。但是控制台就报了这些错误,我们来思考为什么会报这样的错误?

首先它传过来的是一个空值,然后我们又给他赋值了,也就是 myArr.datenum[1] 等于 " ".datenum[1]\

然后我们又想这么写,但是又不想让他报错,我们该如何修改呢?

我们可以给子组件加一个 v-if 用于判断,当flag为false时候不渲染,当数据请求回来了再让他变成true,这样就可以解决子组件的created打印为空的状况

看下面父组件代码

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png" />
    <h1>这是父组件</h1>
    <h1>**********************************</h1>
    <h1>这是子组件</h1>
    <Count :my-arr="myArr" v-if="flag" />
  </div>
</template>

<script>
// @ is an alias to /src
import Count from "./homeView-components/Count.vue"
export default {
  name: "HomeView",
  components: {Count},
  data() {
    return {
      myArr:"",
      flag:false
    };
  },
  mounted() {
    setTimeout(() => {
      this.myArr = {"datenum":[10,20,30]};
      this.flag = true
      console.log("父组件对象更新完毕");
    },2000)
  },
};
</script>

看浏览器

image.png

以上就是今天的面试题分析了