I’ve said it once and I’ll say it again a thousand times: Vue is a fantastic framework. But there’s a part of it I see being misunderstood and somewhat misused fairly often, whether it’s from developers on my team, published plugins, or even developers looking for help in the Vue slack channel. And that is the
v-bind syntax when used with html attributes and props.
I get slightly triggered when I come across something along the lines of
<my-component v-bind:custom-prop-text="'Hello World'"></my-component> in the wild. If you’re asking what’s wrong here, you’re probably one of those people I’m talking about. And that’s completely fine, but it’s fundamentally backwards, and (hopefully) by the end of this article you’ll understand why.
About the syntax
So what is
v-bind? Well, with Vue, you’re able to dynamically bind one or more attributes, or a component prop to an expression directly in the HTML. The magic comes into play when you prepend an attribute with the
Let’s take a standard link.
<a href="http://twitter.com/SamTurrellDev">My twitter</a> for example. What if we wanted to make this dynamic? Well, you might try and link it up to your Vue component data using something like
<a href="user.twitter_link">My twitter</a>. So would this insert the
twitter_link value into our
href? No - you’d just end up with a link to
user.twitter_link in the
href once your page had rendered.
However, when you prepend the
href tag with
v-bind syntax like so:
<a v-bind:href="user.twitter_link">My twitter</a>, you end up with something very different. You see, when Vue recognises that you’re using this directive it will try and resolve the value from the current component/instance data.
In this example
user.twitter_link will try to resolve to
this.user.twitter_link and, assuming you have an object in your data which matches this structure, it will insert the value of
twitter_link into the
href of your link. Great right?
This is a very basic example obviously, and you’re able to pass many different types of data into a
Why this is being used wrong
So let’s go back to our first example:
<my-component v-bind:custom-prop-text="'Hello World'"></my-component>. With what we’ve learnt above, we know that, as we’re using
v-bind, Vue will try and evaluate this data as an expression. The data we’re passing in here is a little different than a path to an object value though, it’s a literal string.
So what does Vue do in this instance? Luckily, it won’t try and find
this.Hello World on the model because that would throw a nasty error, it’s a little smarter than that. It will actually detect that it’s a string, and treat is at such. This means
v-bind:custom-prop-text="'Hello World'" will resolve to
this.customPropText === 'Hello World' in the
my-component component. That’s all good right? Sure, but it still doesn’t make sense.
v-bind on a string allows you to do string interpolation such as
<my-component v-bind:custom-prop-text="'Hello ' + user.first_name"></my-component> which is handy. But we’re not doing that. So what if we drop the
A lot of people think that just because we’re using custom props on a component, we need to use
v-bind in order to pass the value in, but this is incorrect. If we’re using string literals with no need of evaluating it we can get away with the following:
<my-component custom-prop-text="Hello World"></my-component>. When we pass in the data this way, we don’t need Vue to try and work it out because the data will be exactly as we passed it in.
If you’re just passing in a string, you don’t need to use
v-bind at all. There’s no point making Vue try and evaluate something when it doesn’t need to. If it’s not dynamic, don’t force it to be.
I would also drop the
v-bind altogether and use the shorthand colon convention so
v-bind:href="value" would be
:href="value", it reads a lot nicer in my opinion.