Home > Software design >  how to create v-model custom component in Nuxt
how to create v-model custom component in Nuxt

Time:12-01

I am having problems with two-way binding of a custom component in Nuxt. Maybe I'm making a silly mistake somewhere. I would be grateful for any help

#Custom Component Input.vue

<template>
    <input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" class="input" type="text">   
</template>

<script>
export default {
    props:{
        modelValue:String,
    },
}
</script>

<style lang="scss" scoped>
@import '@/assets/_shared.scss';

.input{
    padding: 10px 15px;
    background: white;
    border: 1px solid #cecece;
    border-radius: 4px;
}
</style>

#Page index.vue

<template>
    <section class="new-appeal">
        <form class="new-appeal-form">
            <label class="new-appeal-form-item">
                <Input placeholder="Appeal" v-model.trim="cashier_name"/>
            </label>
            <Button class="submit">Creare appeal</Button>
        </form>
    </section>
</template>

<script>


export default {
    layout:'main',
    data:function(){
        return{
            cashier_name:''
        }
    },
}
</script>

as you can see i'm trying to do two way data binding, but unfortunately it doesn't work

CodePudding user response:

This is working great and is following the conventions.

index.vue

<template>
  <section class="new-appeal">
    <form class="new-appeal-form">
      <label class="new-appeal-form-item">
        <Input v-model.trim="cashierName" placeholder="Appeal" />
      </label>
      <Button class="submit">Creare appeal</Button>
    </form>
  </section>
</template>

<script>
export default {
  layout: 'main',
  data() {
    return {
      cashierName: '',
    }
  },
}
</script>

Input.vue

<template>
  <input
    :value="cashierName"
    class="input"
    type="text"
    @input="$emit('input', $event.target.value)"
  />
</template>

<script>
export default {
  name: 'Input',
  props: {
    cashierName: {
      type: String,
      default: '',
    },
  },
}
</script>

Otherwise, you could have it as following too (I'm still renaming cashier_name to camelCase btw)

index.vue

<template>
  <section class="new-appeal">
    <form class="new-appeal-form">
      <label class="new-appeal-form-item">
        <Input v-model.trim="cashierName" placeholder="Appeal" />
      </label>
      <Button class="submit">Creare appeal</Button>
    </form>
  </section>
</template>

<script>
export default {
  layout: 'main',
  data() {
    return {
      cashierName: '',
    }
  },
}
</script>

Input.vue

<template>
  <input
    :value="cashierName"
    class="input"
    type="text"
    @input="$emit('update:cashierName', $event.target.value)"
  />
</template>

<script>
export default {
  name: 'Input',
  // https://vuejs.org/v2/api/#model
  model: {
    prop: 'cashierName',
    event: 'update:cashierName',
  },
  props: {
    cashierName: {
      type: String,
      default: '',
    },
  },
}
</script>

CodePudding user response:

In Vue 2 you the default v-model value is just value and in order to update the value you have to emit input event. You can't use update:modelValue in vue 2. you should use this way,

<Input placeholder="Appeal" v-model.trim="cashier_name"/>

in your custom Input component

<template>
    <input :value="value" @input="$emit('input', $event.target.value)" class="input" type="text">   
</template>

<script>
  export default {
    props: ['value']
  }
</script>
  • Related