组件props未改变的情况下组件watch的props被意外触发

新手上路,请多包涵

Helloworld组件内watch的props的test被意义触发

环境:
vue2.6.10
vue-cli3

pageA内data属性变化意外会触发Helloworld内侦听watch的test被触发

pageA.vue

<template>
  <div>
    <HelloWorld :test="{hi: hi}"></HelloWorld>{{timer}}
  </div>
</template>

<script>
  import HelloWorld from './HelloWorld'
  export default {
    components: {
      HelloWorld
    },
    data() {
      return {
        timer: 1,
        hi: 'hihii',
      }
    },
    mounted(){
      setInterval(() => {
        this.timer+=1
      }, 1000)
    }
  }
</script>

Helloworld.vue

<template>
  <div class="hello">
    HelloWorld
  </div>
</template>

<script>
  export default {
    name: 'HelloWorld',
    props: {
      test: {
        type: Object,
        default: () => {}
      }
    },
    watch: {
      test(n){
        console.log(n)
      }
    }
  }
</script>

希望是test内生变化时Hellowold内的watch才触发

pageA内引用了Helloworld组件,并向其传递一个test对象,Helloworld内watch了test这个对象,并console.log其值。但当pageA的data内其它属性发生了变化居然导致未产生变化的test的watch触发。

<HelloWorld :test="{hi: hi}"></HelloWorld>

经过测试换成:test="obj"就好了
不能直接:test="{hi: hi}"这样写吗?

pageA 改成传递整个对象就正常了

<template>
  <div>
    <HelloWorld :test="obj"></HelloWorld>
    {{timer}}
    <button @click="testObj">改变组件传参</button>
  </div>
</template>

<script>
  import HelloWorld from './HelloWorld'
  export default {
    components: {
      HelloWorld
    },
    data() {
      return {
        timer: 1,
        hi: 'hihii',
        obj: {

        }
      }
    },
    methods: {
      testObj() {
        this.$set(this.obj, 'hi', 'heihei')
      }
    },
    mounted(){
      setInterval(() => {
        this.timer+=1
      }, 1000)
    }
  }
</script>
阅读 2.3k
2 个回答

数据改变,会重新计算组件,在计算子组件HelloWorld的时候,会发现{hi: hi}和test的值不一样了,道理就和{} !== {}一样,所以触发了watch

新手上路,请多包涵

我测试了一下,两种写法都是会引起watch变化的啊

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题