Subscribe on changes!

Unexpected watch calling for some props with default generating value

avatar
Mar 24th 2021

Version

3.0.7

Reproduction link

https://jsfiddle.net/r328ezot/10/

Steps to reproduce

A child component has these options.

  props: {
    foo: {
      type: Object,
      default: () => ({ val: 1 })
    },
    bar: {
      type: Number,
      default: 0
    },
  },
  setup(props) {
    const count = Vue.ref(0)
    Vue.watch(() => props.foo, () => {
      count.value++
    })
    return { count }
  }

The parent has this template and setup function.

<child :foo="foo" :bar="bar"></child>
<button @click="addBar">Add</button>
setup() {
const foo = Vue.ref()
  const bar = Vue.ref(0)
  function addBar() { bar.value++ }
  return { foo, bar, addBar }
}

When I click 'Add' button to change only bar, the child state 'count' increases: watch callback for prop `foo' is triggered.

If the parent does not pass the prop foo, it is not triggered.

<child :bar="bar"></child>

Is it expected behavior?

What is expected?

Watch callback for foo is not triggered if the value is not changed.

What is actually happening?

Watch callback for foo is triggered if the value is not changed.

avatar
Mar 24th 2021

as a workround:

  const defaultV = { val: 1 }

  props: {
      foo: {
        type: Object,
        default: () => (defaultV)
      },

    }