组件里面的data函数在props更新的时候会重新执行吗?

组件里面的data函数在props更新的时候会重新执行吗?

<!DOCTYPE html>

<html lang="en">

<head>

  <meta charset="UTF-8">

  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <title>Document</title>

</head>

<body>

  

  <div id="app">

      <counter-other v-bind="counterStore"></counter-other>

      <counter v-bind="counterStore"></counter>

      <counter v-bind="counterStore"></counter>

  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

  <script>


    // store对象

    var store = {

      counter: {

        count: 0

      }

    }


    // 定义一个总线Vue实例

    var bus = new Vue();

    // 监听累加action

    bus.$on("countAction", function(newNum){

      // 更新数据

      store.counter.count = newNum;

    })

    // 为了让子组件能够访问到, 让子组件能够发送action

    Vue.prototype.bus = bus;


    // 全局注册组件

    Vue.component("counter", {

      props: ["count"],

      template: `<div @click="incrCount">{{count}}</div>`,

      methods: {

        incrCount(){

          // 发送count更新action

          this.bus.$emit("countAction", this.count+1);

        }

      }

    });

    Vue.component("counterOther", {

      props: ["count"],

      data(){

        return {

          num: this.count

        }

      },

      template: `<div @click="incrCount">{{num}}</div>`,

      methods: {

        incrCount(){

          this.bus.$emit("countAction", this.num+1);

        }

      }

    });


    var app = new Vue({

      el: "#app",

      data: {

        // 拿到counter的store数据

        counterStore: store.counter

      }

    })

  </script>

</body>

</html>


  1. 写了两个组件,counter和counterOther,它们实现的差异就是一个将props变成本地数据,一个是直接使用props。   在点击数字的时候会派发事件, 通过bus去更新全局的store对象。   但是为什么counter组件会更新,counterOther组件却不会? 是不是因为组件内定义的data函数不会重复执行? 

  2. 在官方文档上没有看到bus相关的资料, 这种做法是不是非主流的方式?  不知道是不是自己思路不够清晰, 感觉这种写法不能够应用于中大型项目当中? 

  3. 请问上面这个代码可不可以称之为store模式 ? 


正在回答

登陆购买课程后可参与讨论,去登陆

2回答

同学你好,理解的有些偏差,具体可以参考如下解析理解 :

  1. data方法中声明的属性可以理解为是初始化,只会在组件被创建时执行一次。

  2. 父组件传递给子组件的数据发生改变,子组件确实会更新数据,但不会重新执行 data方法。所以当点击counterOther组件时,只会改变count值,但不会执行data方法,重新给num赋值,所以无法实现效果。

  3. 可以使用老师第一次回复中给同学提供的解决方法,直接在incrCount中改变num的值实现效果,或者使用watch方法通过监听count的改变,实时改变num的值,实现效果,如下:

    http://img1.sycdn.imooc.com//climg/5ecf2c790980b20e06670278.jpg

  4. 同学可以添加created和updated方法输出测试内容,帮助自己更好的理解

    http://img1.sycdn.imooc.com//climg/5ecf2cf00939cfc607700489.jpg

    打印结果如下:created只会执行一次,但数据发生改变时会多次触发updated方法

    http://img1.sycdn.imooc.com//climg/5ecf2d2409e39d4907490260.jpg

同学可以测试理解下,祝学习愉快~

好帮手慕慕子 2020-05-27 17:56:15

同学你好,对于你的问题解答如下:

  1. props发生改变时,会更新子组件中data的数据。

    因为代码中只是将this.num加一的结果作为参数传递给countAction方法,并没有赋值修改this.num的值,所以导致this.num的值一直都是1,页面不会发生改变。

    建议:可以先修改this.num的值,再测试下。

    http://img1.sycdn.imooc.com//climg/5ece33280963eba506810176.jpg

    http://img1.sycdn.imooc.com//climg/5ece333509e65e9e01340081.jpg

  2. 同学理解是对的,这个方法目前确实是较少使用了,但他也是一种基础的实现方式,所以我们也需要学习了解下。

    实际开发中更多的是使用vuex进行状态管理。后面的课程中老师也会结合案例去讲解vuex的使用方法。

    bus是老师自定义的,由于bus这个单词有总线的意思,所以大家编写代码时,默认命名为bus,其实是可以任意命名的,所以在官网中的介绍并不是直接介绍的bus,可能导致同学没有搜到相关的资料,老师这里给同学查找了相关的地址,同学参考官网解析简单了解下即可,https://cn.vuejs.org/v2/guide/migration.html#dispatch-%E5%92%8C-broadcast-%E6%9B%BF%E6%8D%A2 

    http://img1.sycdn.imooc.com//climg/5ece37dc09cbb6d909140710.jpg


  3. 不可以的,可以看看官网中对store使用的相关解释:

    http://img1.sycdn.imooc.com//climg/5ece34360939587808320534.jpg


    具体可以查看官网简单了解下 https://cn.vuejs.org/v2/guide/state-management.html 

    由于store主要是用来处理复杂数据的,所以一般只有在大型项目或者数据较为复杂的项目中才会使用到,目前我们的重点是学习vue相关的基础知识,所以不会涉及store相关的讲解,后面的课程中,老师会结合案例进行简单的讲解,同学到时候可以学习下,


如果我的回答帮助到了你,欢迎采纳,祝学习愉快~

  • 提问者 慕移动3569406 #1
    感谢 orz 后面两个问题明白了, 但是第一个还是有点疑问,不知道这个时间会不会打扰到老师。 疑问是父组件的更新不是应该会造成子组件的更新吗? 既然这样父组件的props更新了,应该会重新执行子组件的data函数,也就是会更新num这个本地数据才对,而组件的本地数据发生变化就会更新子组件的视图。 这是我的一个想法, 希望老师指正一下。
    2020-05-27 19:42:47
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师