typescriptvuejs3v-model

How to create a custom component with two way v-model binding


Imagine the scenario where you have a custom component called coolComponent that consists of three input boxes:

<v-text-field v-model="from"/>
<v-text-field v-model="to"/>
<v-text-field v-model="subject"/>

These three fields actually adhere to a interface coolInterface as follows:

interface CoolInterface {
  from: string;
  to: string;
  subject: string;
}

Surprisingly after years of using vue I have never had to create a custom component that has its own v-model. So I am not sure how to actually do this but I need to create a v-model for my coolComponent such that if its initially set in the parent component the text fields would fill in with the CoolInterface object or if the user makes edits in the text boxes the v-model will update as usual. Hopefully that all makes sense!


Solution

  • The Vue documentation has pretty much all information you need regarding custom component v-model. Child component just needs line of code like const model = defineModel(), now your v-model object from the parent, which implements CoolInterface, is available in the child which you've now named "model", so it would have model.from, model.to, etc...

    Parent.vue

    interface CoolInterface {
      from: string;
      to: string;
      subject: string;
    }
    
    const cool = ref<CoolInterface>({
      from: 'foo',
      to: 'bar',
      subject: 'baz'
    })
    
    <CoolComponent v-model="cool" />
    

    CoolComponent.vue

    const model = defineModel()
    
    <input v-model="model.from"/>
    <input v-model="model.to"/>
    <input v-model="model.subject"/>