Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing v-model into a checkbox inside a Component in Vue 3?

Tags:

vue.js

vuejs3

I want to embed a checkbox inside a Vue3 Component and have the v-model binding passed down to the checkbox.

Inside the Component:

<!-- Tile.vue -->
<template>
  <div>
    <input type=checkbox v-model="$attrs">
  </div>
</template>
<script>
export default {inheritAttrs: false}
</script>

Then in an outside file:

<template>
<Tile value="carrot" v-model="foods" />
<Tile value="tomatoes" v-model="foods" />
</template>
<script setup>
var foods = ref([]);
</script>

How do I achieve this?

The documentation says that v-model is just a shorthand for :modelValue and @update:modelValue but this is not universal as Vue obviously behaves differently for form elements such as smartly listening to onchange instead of oninput and modifying the property checked instead of value depending on the node.

If I use v-model on the outer component, how do I forward it to the checkbox and get the same smart behavior that Vue has?

like image 375
Kernel James Avatar asked Sep 07 '25 13:09

Kernel James


1 Answers

I have found tons of controversial information. Some recommend using @input event (Vue 3 custom checkbox component with v-model and array of items). Some recommend emitting modelValue:update instead of update:modelValue (https://github.com/vuejs/core/issues/2667#issuecomment-732886315). Etc.. Following worked for me after hour of trial and error on latest Vuejs3

Child

<template>
  <div class="form-check noselect">
    <input class="form-check-input" type="checkbox" :id="id" :checked="modelValue" @change="$emit('update:modelValue', $event.target.checked)" />
    <label class="form-check-label" :for="id"><slot /></label>
  </div>
</template>

<script>
import { v4 as uuidv4 } from "uuid";

export default {
  inheritAttrs: false,
  emits: ["update:modelValue"],
  props: {
    modelValue: {
      type: Boolean,
      required: true,
    },
  },
  setup() {
    return {
      id: uuidv4(),
    };
  },
};
</script>

Parent:

<Checkbox v-model="someVariable">Is true?</Checkbox>

you can verify that it works but doing this in parent:

    var someVariable= ref(false);

    watch(someVariable, () => {
      console.log(someVariable.value);
    });

p.s. The other solution above does not work for me. Author recommends using value property. But in example he passes v-model attribute. So I don't know exactly how it's supposed to work.

like image 192
Alex Avatar answered Sep 11 '25 02:09

Alex