Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

vijay.rangan's avatar

Props without values (think attributes) in Vuejs

Hey guys,

I was wondering if it's possible to do something like this in Vue

<div spacer>
</div>

That would achieve the same result as

<div :spacer="true">
</div>

So basically I need to know if we can have attribute like syntax in Vue where we can detect the usage / presence of a prop instead of having verbose syntax like above.

Any help is much appreciated !

Thanks in advance :)

0 likes
18 replies
viktorivanov's avatar

You have to use v-bind or : syntax to pass data from the parent scope to your component's scope. If you omit them and just use spacer="true" Vue will interpret your spacer prop as the string "true" and not the boolean true.

vijay.rangan's avatar

Yup I know that :) if you look at the code above that's what I've used. But, I don't want to pass any value. Think of it as passing something like the disabled attribute on input elements. You dont necessarily have to say disabled=disabled; just the presence of it communicates to the elements the desired functionality.

goatshark's avatar

@vijay.rangan As per your example, could you not just set the value in your Vue data instead of it having to come from a prop? Don't data arrays/objects/variables behave the same as passed in props?

vijay.rangan's avatar

Data in vue js is a way of the component itself holding its state. A prop is a mechanism for parent components to pass data into the child. One of the reasons we don't mix props and components data is so that the state of our application is easy to reason about. So, I don't want to hold the prop as state; I might as well use :spacer="true". Using the attributes feels a lot cleaner to me and more intuitive for user of the component.

tjames's avatar

No it's not possible. The very point of 'props' is to pass properties from parent to child, by omitting the ="prop", you're not passing anything and vue treats it as undefined.

vijay.rangan's avatar

@tjames yeah that's the conclusion I drew as well. Thought the community here may have had the answer. But, there is an issue raised I think with Evan (creator of Vuejs) regd this. Unable to find it though :(

jimmck's avatar

props are attributes. In HTML some attributes are pre-processed by the rendering engine, i.e. class or style etc... Other unrecognized attributes are ignored but are available in the DOM for query. Vue has a prop array to define these attributes for a component. Its is not a specific mechanism for a parent to pass data to a child. Users can set attributes in a components markup. I seem many uses where data is passed into a view object as a prop when it should be a true data member. Empty properties serve no useful purpose. props can have a default value and this will enforced by the component when the prop is not set.

vijay.rangan's avatar

Hmm. That isn't necessarily true. Props exist for a number of reasons and like I said it provides a mechanism for passing data between parent and child. I'm not saying that one MUST not use props to hold state. So, let mr then rephrase my question, can we have cuatom attributes in vuejs. I know for a fact that it's possible with native web components. I'd like to know how we can achieve the same with vue

jimmck's avatar

@vijay.rangan Of course. Consider...

                <mylistibox size="7"/>
    Vue.component('mylistbox', {
        el: function () {return '#complist' + this.id},
        //template: "#listbox-template",
        props: ['size', 'doselect', 'id'],
        data: function () {
            return {
                list: null,
                selected: -1,
                selectOptions: [],
                selectHandler: null
            }
        },
...

size, doselect and id in the props array are available to the component.

vijay.rangan's avatar
vijay.rangan
OP
Best Answer
Level 15

@jimmck I know that but that's not what I was asking :) Anywhoo, I found the answer I was looking for; did a little digging through the source code. So for anyone with a use-case similar to mine, here's the solution.

First off, here's the requirement :

<div my-custom-attribute></div>

Notice how I'm not using v-bind or :my-custom-attribute="value". If you would like to look for the "presence" of a custom attribute, here's how. On your Vue instance, you can access attributes like so :

this.$el.attributes

This will give you a 0-based index array of attributes specified on the element. Now that we have our attributes array, we can fetch the one we need, for example my-custom-attribute like so :

this.$el.attributes.getNamedItem('my-custom-attribute')

Now that we know how to detect / find our attributes, we can do any computation with it.

jimmck's avatar

@vijay.rangan No idea where you going with all of this. I detect attributes just fine. binding ":" pertains to 2-way messaging of values. In any event I don't reference parameters with default values unless present, empty attributes or parameters have no useful value for me. I use Vue props to configure components and binding for read/write access between objects. Vue is just another useful abstraction of a webpages DOM.

vijay.rangan's avatar

@jimmck absolutely agree with everything you just said. I was looking for alternative ways of accomplishing a certain task and I just wanted syntactic sugar while consuming my components and that's where I'm going will this :)

Mottokrosh's avatar

@vijay.rangan I just had the same requirement, and I solved it by checking this.$el.getAttributeNode('my-custom-attribute') inside mounted(). I was sort of hoping I could use your solution inside computed or data(), but of course this.$el doesn't exist yet at that point. Still, thanks for the alternative method!

1 like
mohammadrida's avatar

@Mottokrosh how i can get attributes for specific element ? "this.$el" this will show all elements on components

Mottokrosh's avatar

@vijay.rangan And then just now I find the proper, very simple way to do this!

Just specify your prop type, and it will work as expected:

props: { 'spacer': Boolean }

Now it's handled like regular HTML element attributes. That means that in each of these cases, this.spacer is true: <div spacer />, <div spacer="spacer" />, and <div :spacer="true" />, but false in e.g. <div spacer="true" />, and <div spacer="other">.

Hope that helps! Just made my code much simpler.

4 likes

Please or to participate in this conversation.