Setting the default value of a select tag in Vue.js

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!

2 comments

  1. What syntax is this? It just throws errors at “default: () => { ” according to the documentation it should be:
    default: function () {
    return { msg: ‘hello’ }
    }

    1. 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!

Leave a comment

Your email address will not be published.