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

lindstrom's avatar

Vue Default Selection for Select

Getting my feet wet with Vue and I'm looking for validation of my implementation of selecting a default value for a select input.

I have a component with a simple form. I pass company data to it for use in populating select options. This works and is (approximately) what I have:

<create-account :company="{{ $companies->toJson() }}"></create-account>

Inside the component:

<template>
// form fields
    // is binding data like what follows kosher?
    <select v-model="form.company_id, selected" 
                  name="company_id">
        <option v-for="company in companies"
                        :value="company.id"
                        v-text="company.name"></option>
    </select>
// more fields
</template>

<script>
    export default {
        props: ['companies'],
        data() {
            return {
                form: new Form({
                    name: '',
                    display_name: '',
                    company_id: '1 ', // initial value
                    phone: '',
                }),
                selected: '1' // value of desired selection
            }
        },
// methods etc
}
</script>

Didn't really find anything to support this so I can only assume this is how it's done. Are there other, more "correct", ways to achieve the same thing? Thanks for any, ah hem, input!

0 likes
5 replies
dextercampos's avatar

You don't need to bind form.company_id into the select. Also, as far as I know you can't do multiple bindings for v-model just like what you did.

All you need to do is v-model=selected and set the default value in your data - just like what you did. You now can remove company_id in you new Form({...}).

Final result would be similar to this:

<template>
// form fields
    // bind selected to this form input
    <select v-model="selected" 
                  name="company_id">
        <option v-for="company in companies"
                        :value="company.id"
                        v-text="company.name"></option>
    </select>
// more fields
</template>

<script>
    export default {
        props: ['companies'],
        data() {
            return {
                form: new Form({
                    name: '',
                    display_name: '',
                    phone: '',
                }),
                selected: '1' // initial value. This will automatically change when a diff value is selected in the input.
            }
        },
// methods etc
}
</script>
burlresearch's avatar

There are nice plugins for this which provide all the functionality you'd ever want:

Both of these automate everything about selects in Vue, with a little configuration. Let us know if you're interested in going this route, or if you really want to code-your-own.

lindstrom's avatar

Hey, @dextercampos, thanks for responding! You're right, what I had was totally wrong and I could see that clearly when I looked again in devtools.

However, I do have to bind form.company_id or it won't get passed to the form object for submission. Here's where I ended up which actually does work and seems much more reasonable:

<template>
// form fields
    <select v-model="form.company_id" 
                  name="company_id">
        <option v-for="company in companies"
                        :value="company.id"
            :selected="selected" // Vue will make the option selected if the bound value matches the selected value.
                        v-text="company.name"></option>
    </select>
// more fields
</template>

<script>
    export default {
        props: ['companies'],
        data() {
            return {
                form: new Form({
            company_id: '1', // this will change when a new value is selected
                    name: '',
                    display_name: '',
                    phone: '',
                }),
                selected: '1' // initial value. This WILL NOT change when a diff value is selected which is fine
            }
        },
// methods etc
}
</script>

I think I tried to use a conditional or something dumb when I bound :selected without thinking that, of course, Vue is smart enough to do that for me. I legit couldn't find any good examples of how to do the above.

@burlresearch, I think vue-select would be ideal, but (IIRC) I had CSS issues when I tried it for a multiselect. I'm fine with wiring it up myself although multiselect with a search/lookup and tags (like select2/vue-select) may be more than I want to bite off right now. Guessing that most folks are using one of the two plugins you mention because there isn't very much out there about doing this kind of stuff. If you have anything else relevant, I'd love to have a look!

burlresearch's avatar

Once I figured out vue-select, which works fine for either single or multiple select inputs, I have been using them ever since - they do simplify a lot of logic, and I hate excessive javascript:

<template>
  <form @submit.prevent="submit">
    <form-group id="company" label-for="company" label="Company">
      <v-select :options="companies" v-model="formdata.company"></v-select>
    </form-group>
  </form>
</template>

<script>
  import vSelect from 'vue-select';

  export default {
    components: {vSelect},
    data() {
      return {
        form: new Form,
        formdata: {},
        companies: [
          {'value': 1, 'label': 'Acme Inc'},
          {'value': 2, 'label': 'Beta Ltd'},
          {'value': 3, 'label': 'Chaz Co.'},
        ],
      };
    },
    methods: {
      submit() {
        this.form.save('/form-end-point', this.formdata)
          .then(() => console.log('submitted'))
          .catch(err => console.log('ERRORS', err.response));
      },
    },
  };
</script>
2 likes

Please or to participate in this conversation.