Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for v-bind:content shorthand, including namespaced attributes (supersedes #2858) #2877

Closed
wants to merge 2 commits into from

Conversation

bopjesvla
Copy link

I originally submitted this as a PR to phanan's #2858, but that's probably more trouble than it's worth. This PR includes phanan's original PR:

With this commit, v-bind with an empty expression will imply the expression to be the directive name, i.e. v-bind :content will have the same effect as v-bind:content="content", :href will have the same effect as :href="href" and so on so forth. Note that only attribute bindings are affected by this change. Event, transition, class/style bindings etc. remain untouched.

Not sure if I'm missing anything here – all unit tests passed fine, though. Let me know if there's anything to fix or improve, or just close this PR if you don't intend to support the feature.

But it also includes support and tests for attributes with non-word characters other than hyphens as described here:

Something I just thought of: v-bind:data-content and v-bind:ns:attr should be equivalent to v-bind:data-content="dataContent" and v-bind:ns:attr="nsAttr", respectively.

An Phan and others added 2 commits May 12, 2016 15:39
This commit aims to add support for `v-bind:content` shorthand. With
this, v-bind with an empty expression will imply the expression to be
the directive name, i.e. `v-bind :content` will have the same effect as
`v-bind:content="content"`, `:href` will have the same effect as
`:href="href"` and so on so forth.

Only attribute bindings are affected by this change. Event, transition,
class/style bindings remain unchanged.
@LinusBorg
Copy link
Member

I like this!

@yyx990803
Copy link
Member

Took me some time to respond this because I am not really a fan of this proposal but it wasn't immediately clear to me what turned me off. I tried it out and it just felt weird to me:

<comp :a :b></comp>

Now I realize it's because of the semantic implication of HTML attributes that have no values - they are usually boolean attributes. An attribute with no value indicates the "presence of an attribute" or "truthiness". Implicitly expanding to a binding overloads this perception.

In addition - if a prop in the child component is declared with type Boolean, the presence of the attribute indicates a true value. This would cause prop and :prop to have very different meanings, and is technically a breaking change.

@yyx990803
Copy link
Member

Forgot to mention though - thanks to both @phanan and @bopjesvla for taking a stab at implementing this. Appreciate your effort and sorry for the late response.

@phanan
Copy link
Member

phanan commented Jun 17, 2016

👍 Perfect explanation, thanks Evan.

Edit: Note to self: From now on, whenever I see the word "imply" in my PR, I'll need to take a step back and think twice ;)

@rpkilby
Copy link

rpkilby commented Jun 17, 2016

Zen of python, "explicit is better than implicit" ;)

@maurop123
Copy link

maurop123 commented Jun 7, 2017

The solution @sirlancelot proposed in #5835 seems like it should be in this thread:

If you're using ES6 already (via webpack's vue-loader), you can try
<my-component v-bind="{ propA, propB, propC }">

@RashadSaleh
Copy link

RashadSaleh commented Oct 13, 2022

What if we use ::a for :a="a"?
This way it is not a breaking change (I think), and it should not cause any "double meaning" issues with how HTML attributes work.

My actual use case is a little too specific so I am going to use a fictional but simpler use case, where an alert modal can have a <router-link>, but the context decides where that goes to.

<template>
    <LinkModal :text="Sign In" :to="'/sign-in'">
        You have to sign in first!
    </LinkModal>
</template>
<template>
    <dialog>
        <slot></slot>
        <router-link ::to >{{ text }}</router-link>
    </dialog>
</template>

This is more elegant than doing <router-link :to="to"> and becomes increasingly so if there are more than just the to property. Also it can be even more elegant for native HTML attributes that are to be provided a value from <script> inside the component. Example:

<script setup>
let max = ref(100);
let min = ref(10);
</script>

<template>
    <input type="range" ::max ::min>
</template>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants