I recently came a cross a small stumbling block when rendering a select box from data passed to my component via props.
This is my component:
<template>
<select v-model="tag">
<option value="">Choose...</option>
<option v-for="tag in tags" v-bind:value="tag.id">{{ tag.name }}</option>
</select>
</template>
<script>
export default {
props: {
tags: Array,
tag: String
}
};
</script>
And I’m including it in a parent Vue instance like so:
<search-filters :tags="tags" :tag="store.state.query.tag_id"></search-filters>
The Problem
I want to be able to set the selected tag from my parent instance. This works fine using the code above – the problem occurs when the current tag_id is not set in my store object.
When the tag_id is not set in my store object, I want my component to default to the “Choose…” option.
Digging Deeper
When the tag_id is not defined in my store object, it’s being set as null on my component. I thought this was what I wanted, but this does not select the “Choose..” option by default since the Html value of the option is an empty string. What I actually want is the tag to explicitly be an empty string when it isn’t set.
The Solution
While I could probably perform a quick check when including my component and do something like the following:
<search-filters :tags="tags" :tag="store.state.query.tag_id ?: ''"></search-filters>
It doesn’t solve the problem if this component is going to be included in many places. It also makes my component somewhat brittle since it relies on being instantiated in a particular way.
Instead, I resorted to setting a default value for my “tag” prop. This default value is used when the :tag prop isn’t passed, or is null – just what I wanted!
The code to set a default value to the prop is lifted from the vue.js documentation:
<script>
export default {
props: {
tags: Array,
tag: {
type: String,
default() {
return '';
}
}
}
};
</script>
Simples!
What syntax is this? It just throws errors at “default: () => { ” according to the documentation it should be:
default: function () {
return { msg: ‘hello’ }
}
Hey! You’re right – I actually had a typo in my code where I mixed up a couple of concepts. I’ve updated it to use ES2015 syntax.
Thanks for pointing it out!