Skip to content

[BUG]: withDefaults Fails When Using Function Declarations With Props #12822

Open
@SFM61319

Description

@SFM61319

Vue version

3.4.15

Link to minimal reproduction

https://play.vuejs.org/#eNqFUslOwzAQ/ZWRL7RSlVDBKaStWCWQgAo4+pKmkzYlsS3b6aIq/87YaUKRgN7secs8z3jPrpUK1hWyiMUm1bmyYNBWCopELEacWcPZmIu8VFJbuJWlgkzLEs6C0F2c9OyKizhsxESli8VSFYlFugHEXhTNEk12Q84gpHIcHnHYgNqkUmT5IlgZKSjL3ik5S0maF6hflc2loCgReMRhSVHIzZOvWV3hoK2nS0w/f6mvzNbVOJtqNKjXyFmH2UQv0Dbw/fsLbuncgaWcVwWx/wHf0Miichkb2k0l5hT7iOfTPvop5mLxYe63FoVpH+WCOmbt+ZzRVN3U/nr6d9yL4NLruKhpiu1GTizT7hTC826qpTIwamwzKScRiKqcoaZ9AtC+jgvUgQvakbGgDrpNbpd3mCVVYU1vjlku0FvGB+txrz/ozCPoeV0fRuP2IZqyadH4BdQPJhM4982bOVDppIysnWzYyer+ie+4HI4fXJ79/siiruOQgJZw4zp3BBetI/z8ufUXUsMTpg==

Steps to reproduce

Change the default props factories to use object function declaration syntax and notice the output vanishing due to the error thrown.

Working code

const props = withDefaults(defineProps<MyProps>(), {
  foo: (props) => {
    return props.bar ?? 0;
  },
  bar: (props) => {
    return props.foo ?? 0;
  },
});

Breaking code

const props = withDefaults(defineProps<MyProps>(), {
  foo(props) {
    return props.bar ?? 0;
  },
  bar(props) {
    return props.foo ?? 0;
  },
});

What is expected?

Default prop value resolution with props arg to work as usual irrespective of the function syntax used.

What is actually happening?

Default prop value resolution with props arg is not working when using the object function syntax, it only works when arrow function syntax is used.

System Info

System:
  OS: Linux 6.12 Arch Linux
  CPU: (12) x64 12th Gen Intel(R) Core(TM) i5-12450H
  Memory: 1.60 GB / 15.33 GB
  Container: Yes
  Shell: 5.2.37 - /usr/bin/bash
Binaries:
  Node: 18.20.4 - /run/user/1000/fnm_multishells/99919_1738935943852/bin/node
  npm: 10.9.0 - /run/user/1000/fnm_multishells/99919_1738935943852/bin/npm
npmPackages:
  vue: ^3.4.15 => 3.4.20

Any additional comments?

I also noticed that the passed props argument's state is persisting across default props factories, possibly in the order defined. In the playground example, if foo alone is passed, bar is being set to foo's value as expected, but when bar alone is passed instead, foo is not being set to bar's value. I am not sure if this is intended behavior, considering that one can fairly assume that the props arg passed to the default props factories contains only the original props passed by the user and is not mutated by default factories defined before the current factory. And the lack of dedicated docs for withDefaults makes it harder to understand.

Metadata

Metadata

Assignees

No one assigned

    Labels

    🔨 p3-minor-bugPriority 3: this fixes a bug, but is an edge case that only affects very specific usage.has workaroundA workaround has been found to avoid the problemscope: sfc

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions