vuejs / rfcs

RFCs for substantial changes / feature additions to Vue core
4.86k stars 548 forks source link

v-bind merge strategy modifier #215

Open CyberAP opened 3 years ago

CyberAP commented 3 years ago
  1. Revert v-bind merge behaviour to the one used in Vue 2.
  2. Add .replace modifier to force attribute replacement.

Rendered RFC

posva commented 3 years ago

I agree on not relying on order to decide the outcome of combining v-bind with a regular attribute. But this RFC is only approaching the problem with the idea of not creating a breaking change instead of comparing the two existing solutions and why one would make more sense than the other or if both are as valuable.

Regarding .replace, I think it's worth exposing why there should be some mechanism to let v-bind take the lead (which is connected to my point above)

CyberAP commented 3 years ago

But this RFC is only approaching the problem with the idea of not creating a breaking change instead of comparing the two existing solutions and why one would make more sense than the other or if both are as valuable.

This RFC is actually a breaking change for current Vue 3 users and I didn't find any solution to fix order dependency that would still not be a breaking change. I didn't go deep into why this change was needed because I do not fully understand the logic behind it (that's why this RFC was created in a first place), unfortunately I couldn't find any information on the motivation of this change. I would be glad if someone provides a link to the explainer so I can reference it in RFC.

Regarding .replace, I think it's worth exposing why there should be some mechanism to let v-bind take the lead (which is connected to my point above)

I think It is a handy tool to provide default values for element attributes. You would have to filter them out otherwise or define that value for each attribute.

<!--these are equal-->
<input :disabled="'disabled' in $attrs ? $attrs.disabled : 'disabled'" v-bind="$attrs">
<input disabled v-bind.replace="$attrs">

But if only Vue 2 behaviour is retained (omitting the .replace modifier change) that would still suffice.

backbone87 commented 3 years ago

the attribute order argument is well understandable, but then how much is it worth, when in some other common vue practices HTML/XML consistency is not followed either (case-sensitive v-on, PascalCase tag names).

personally i have a lot of use cases like component wrappers, where you want to pass through attrs and have some default attributes set (overwriteable), but also have some non-overwriteable attributes, which would end up in code like this:

<template>
  <wrapped-component v-bind="{ a: 'default-value-for-a', ...$attrs }" b="some-fixed-value-for-b" />
</template>

with the current vue 3 behavior, this can be rewritten as the more concise:

<template>
  <wrapped-component a="default-value-for-a" v-bind="$attrs" b="some-fixed-value-for-b" />
</template>

the question remains, if it is worth the BC break (compared to vue 2).

regarding .replace: i would not introduce this. you can always go for v-bind + spread attrs to achieve any behavior you want.

CyberAP commented 3 years ago

how much is it worth, when in some other common vue practices HTML/XML consistency is not followed either (case-sensitive v-on, PascalCase tag names).

Consider this: when we do not have any reliance on the attribute order the complexity of managing an element\component grows linearly with the amount of attributes used. When we have attribute order that complexity grows exponentially, since you now how to scan every single attribute in order to get a full understanding of what's going on. I don't think its worth that mental overhead.

replygirl commented 3 years ago

I've never found myself in a scenario where I was binding something dynamically that I wanted to be overridden by an attribute. Sometimes I'll spread into an object I'm binding, but usually a v-bind and a prop and the same time means to me that local state is overriding a default.

Why not just add a modifier such as .initial for people who want the legacy behavior, instead of introducing a breaking change?