Skip to content

Confusion on and additional subtleties of v-bind.sync #1562

@davidkhess

Description

@davidkhess

This is a complex topic and I might be missing something, but....

I think the docs at https://vuejs.org/v2/guide/components-custom-events.html#sync-Modifier could use three updates:

  1. There should be some mention that .sync can only be used when the expression is a proper lvalue/reference. For instance: :title.sync="title"

:title.sync="title + '!'" won't work. It will generate an error along the lines of:

SyntaxError: Left hand side of operator '=' must be a reference.

Fiddle: https://jsfiddle.net/davidkhess/vs1rxwLh/3/

  1. When an object is used with v-bind, I think it would be worth mentioning that unlike normal bindings with .sync that update the referenced key on the Vue instance's data (i.e. 1. above), in this case it is only going to update that literal key on the object used in the v-bind.

At least, this is my understanding of things looking at the implementation:

vuejs/vue@3965e50

Fiddle: https://jsfiddle.net/davidkhess/vs1rxwLh/33/

  1. Re: this warning:

Using v-bind.sync with a literal object, such as in v-bind.sync=”{ title: doc.title }”, will not work. If you want to include multiple, unrelated data properties in the same v-bind.sync, we recommend creating a computed property that returns an object.

I think it would help to explain why a literal object doesn't work. I believe the reason is that a literal object is not going to be reactive since it isn't attached to a Vue instance's data and therefore the param on the child component will not be updated when the object's attribute is updated. The resolution is to make sure it is reactive and a computed property will do that.

However, I think the recommended solution of a computed property creates more confusion since based on 2. above, the $emit("update:...") is going to update an attribute of the object returned by the computed property which goes against the spirit of a computed property and is not easily accessible. I think it might be more useful to recommend attaching a params object to the parent's data so that the parent component can more easily watch an attribute of the params object for changes from the child component if needed.

EDIT: I'm not able to get the computed approach to work https://jsfiddle.net/davidkhess/vs1rxwLh/22/

I think it's because an object returned from a computed is not reactive.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions