title: How to bind the value attribute on a custom select component tag
body: <p>Im actually new to Vue &amp; NuxtJS. Back in school we are actually doing some Vue and NuxtJS and along with the courses, I'm also trying to read the docs in other to learn more.</p>
  <p>While doing some tutorials given by our teacher, there was a functionality named create course and in there there was a select-option tag where we could choose the project category (i.e. Web or Mobile Development) and on reading the docs I read about this best practice of always creating reusable components. Knowing that, I decided to create my custom select-option tag as follows:</p>
  <p><strong>SelectOptions.vue</strong></p>
  <pre><code>&lt;template&gt;
    &lt;div class=&quot;mb-4&quot;&gt;
      &lt;div class=&quot;relative&quot;&gt;
        &lt;select
          class=&quot;block appearance-none w-full bg-gray-200 border border-gray-200 text-gray-700 py-3 px-4 pr-8 rounded leading-tight focus:outline-none focus:bg-white focus:border-gray-500&quot;
          :class=&quot;[error ? 'border-red-600 focus:border-red-600' : '']&quot;
          @change=&quot;change&quot;
        &gt;
          &lt;option value=&quot;default&quot;&gt;Select Category&lt;/option&gt;
          &lt;option
            v-for=&quot;option in options&quot;
            :key=&quot;option._id&quot;
            :value=&quot;option.name&quot;
            :selected=&quot;selectedOption(option)&quot;
          &gt;
            {{ option.name }}
          &lt;/option&gt;
        &lt;/select&gt;
        &lt;div
          class=&quot;pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-gray-700&quot;
        &gt;
          &lt;svg
            class=&quot;fill-current h-4 w-4&quot;
            xmlns=&quot;http://www.w3.org/2000/svg&quot;
            viewBox=&quot;0 0 20 20&quot;
          &gt;
            &lt;path
              d=&quot;M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z&quot;
            /&gt;
          &lt;/svg&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      &lt;span v-if=&quot;error&quot;&gt;
        &lt;p class=&quot;text-xs italic text-red-600&quot;&gt;
          &lt;slot&gt;&lt;/slot&gt;
        &lt;/p&gt;
      &lt;/span&gt;
    &lt;/div&gt;
  &lt;/template&gt;
  
  &lt;script&gt;
  export default {
    props: [&quot;options&quot;, &quot;value&quot;, &quot;error&quot;],
    data() {
      return {
        selected: null,
      };
    },
    methods: {
      selectedOption(option) {
        if (this.value) {
          return option.name === this.value.name;
        }
        return false;
      },
      change(e) {
        const selectedName = e.target.value;
        const option = this.options.find((option) =&gt; {
          return selectedName === option.name;
        });
        this.$emit(&quot;input&quot;, option);
      },
    },
  };
  &lt;/script&gt;
  
  &lt;style&gt;&lt;/style&gt;
  </code></pre>
  <p>It worked fine I could select the project category and also update my Vuex store. But further in the tutorial the teacher created another select-option tag to update the project status. Like when you click on update, the app loads the project data from the database and you can update it's status from published to active. Here is what was in the tutorial:</p>
  <p>Teacher's select-option tag</p>
  <pre><code>&lt;select
      :value=&quot;project.status&quot;
      @input=&quot;($event) =&gt; emitProjectValue($event, 'status')&quot;
    &gt;
      &lt;option value=&quot;default&quot;&gt;Change Status&lt;/option&gt;
      &lt;option value=&quot;active&quot;&gt;Active&lt;/option&gt;
      &lt;option value=&quot;published&quot;&gt;Published&lt;/option&gt;
    &lt;/select&gt;
  </code></pre>
  <p>Seeing that, I first decided to update my component for it to include the possibility to change the project status, and here is how I did it:</p>
  <p><strong>SelectOption.vue (Update)</strong></p>
  <pre><code>&lt;template&gt;
    &lt;div class=&quot;mb-4&quot;&gt;
      &lt;div class=&quot;relative&quot;&gt;
        &lt;select
          class=&quot;block appearance-none w-full bg-gray-200 border border-gray-200 text-gray-700 py-3 px-4 pr-8 rounded leading-tight focus:outline-none focus:bg-white focus:border-gray-500&quot;
          :class=&quot;[error ? 'border-red-600 focus:border-red-600' : '']&quot;
          @change=&quot;change&quot;
        &gt;
          &lt;template v-if=&quot;status&quot;&gt;
            &lt;option value=&quot;default&quot;&gt;Change Status&lt;/option&gt;
            &lt;option value=&quot;active&quot;&gt;Active&lt;/option&gt;
            &lt;option value=&quot;published&quot;&gt; Published&lt;/option&gt;
          &lt;/template&gt;
          &lt;template v-else&gt;
            &lt;option value=&quot;default&quot;&gt;Select Category&lt;/option&gt;
            &lt;option
              v-for=&quot;option in options&quot;
              :key=&quot;option._id&quot;
              :value=&quot;option.name&quot;
              :selected=&quot;selectedOption(option)&quot;
              &gt;{{ option.name }}&lt;/option
            &gt;
          &lt;/template&gt;
        &lt;/select&gt;
        &lt;div
          class=&quot;pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-gray-700&quot;
        &gt;
          &lt;svg
            class=&quot;fill-current h-4 w-4&quot;
            xmlns=&quot;http://www.w3.org/2000/svg&quot;
            viewBox=&quot;0 0 20 20&quot;
          &gt;
            &lt;path
              d=&quot;M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z&quot;
            /&gt;
          &lt;/svg&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      &lt;span v-if=&quot;error&quot;&gt;
        &lt;p class=&quot;text-xs italic text-red-600&quot;&gt;
          &lt;slot&gt;&lt;/slot&gt;
        &lt;/p&gt;
      &lt;/span&gt;
    &lt;/div&gt;
  &lt;/template&gt;
  
  &lt;script&gt;
  export default {
    props: [&quot;options&quot;, &quot;value&quot;, &quot;error&quot;, &quot;status&quot;],
    data() {
      return {
        selected: null
      };
    },
    methods: {
      selectedOption(option) {
        if (this.value) {
          return option.name === this.value.name;
        }
        return false;
      },
      change(e) {
        if (this.status) {
          this.$emit(&quot;input&quot;, e.target.value);
        } else {
          const selectedName = e.target.value;
          const option = this.options.find(option =&gt; {
            return selectedName === option.name;
          });
          this.$emit(&quot;input&quot;, option);
        }
      }
    }
  };
  &lt;/script&gt;
  
  &lt;style&gt;&lt;/style&gt;
  </code></pre>
  <p>Having that, I then called my component just like he did:</p>
  <pre><code>&lt;SelectOption
   :value=&quot;project.status&quot;
   status=&quot;true&quot;
   @input=&quot;$event =&gt; emitProjectValue($event, 'status')&quot;
  &gt;&lt;/SelectOption&gt;
  </code></pre>
  <p>In the teacher's tutorial, at the moment he refreshed his page, the select tag showed the current course status that is <code>Published</code> but mine still showed <code>Change Status</code>. But apart from that I was still able to update the store.</p>
  <p>So my questions are how can I refactor my component to have that same effect on refresh on binding the value attribute. And secondly I will be really grateful If you guys could give me some clues or ideas on how to optimize my component.</p>
  <p>Thanks to you all</p>