Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

186
Vistas
Vue 3 custom checkbox component with v-model and array of items

Desperately in need of your help guys.

So basically I have a custom checkbox component whit a v-model. I use a v-for loop on the component to display checkboxes with the names from the array. In the parent component I have two columns Available and Selected. The idea is that if I check one of the boxes in the Available column it should appear on the Selected column. The problem is that it displays letter by letter and not the full name.

I am able to achieve the desired result without having a checkbox component, but since I will be needing checkboxes a lot throught my project I want to have a component for it.

Please follow the link for the code: CodeSandBox

Dont mind the difference in styling.

The problem:

Problem

The desired outcome:

Desired outcome

about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

There are two problems. The first problem is, that you have your v-model set to v-model="filter.filterCollection", so a checkbox you select will be stored into the array as a string and if you select another checkbox the string gets overwritten. The second problem is, that you call that stored string as an array. That causes, that your string, which is an array of letters, will be rendered for each letter. So 'Number' is like ["N", "u", "m", "b", "e", "r"].

To solve your problem, you need to store every selection with its own reference in your v-model. To cover your needs of correct listing and correct deleting you need to apply the following changes:

Your checkbox loop

<Checkbox
   v-for="(item, index) in items"
   :key="item.id"
   :label="item.name"
   :id="index"
   :isChecked="isChecked(index)" // this is new
   @remove-selected-filter="removeSelectedFilter" // This is new
   :modelValue="item.name"
   v-model="filter.filterCollection[index]" // Change this
/>

Your v-model

filter: {
        filterCollection: {} // Object instead of array
      }

Methods in FilterPopUp.vue

methods: {
    removeSelectedFilter(index) {
      delete this.filter.filterCollection[index];
    },
    isChecked(index) {
      return !!this.filter.filterCollection[index];
    }
  }

Your Checkbox.vue:

<template>
  <label>
    <p>{{ label }}</p>
    <input
      type="checkbox"
      :id="id"
      :value="modelValue"
      :checked="isChecked"
      @change="emitUncheck($event.target.checked)"
      @input="$emit('update:modelValue', $event.target.value)"
    />
    <span class="checkmark"></span>
  </label>
</template>

<script>
export default {
  name: "Checkbox",
  props: {
    modelValue: { type: String, default: "" },
    isChecked: Boolean,
    label: { type: String },
    value: { type: Array },
    id: { type: Number },
  },
  methods: {
    emitUncheck(event) {
      if(!event){
        this.$emit('remove-selected-filter', this.id);
      }
    }
  }
};
</script>

This should now display your items properly, delete the items properly and unselect the checkboxes after deleting the items.

about 4 years ago · Juan Pablo Isaza Denunciar

0

StevenSiebert has correctly pointed to your errors.

But his solution is not complete, since the filters will not be removed from the collection when you uncheck one of them.

Here is my complete solution of your checkbox working as expected:

Checkbox.vue

<template>
  <label>
    <p>{{ label }}</p>
    <input
      type="checkbox"
      :id="id"
      v-model="checked"
      @change="$emit('change', { id: this.id, checked: this.checked})"
    />
    <span class="checkmark"></span>
  </label>
</template>

<script>
export default {
  name: "Checkbox",
  props: {
    modelValue: { type: Boolean, default: false },
    label: { type: String },
    id: { type: Number },
  },
  emits: ["change"],
  data() {
    return {
      checked: this.modelValue
    };
  }
};
</script>

FilterPopUp.vue

<template>
   ...
       <Checkbox
          v-for="(item, index) in items"
          :key="index"
          :label="item.name"
          :id="index"
          @change="onChange"
        />
  ...            

</template>

<script>
...
methods: {
    removeSelectedFilter(index) {
      this.filter.filterCollection.splice(index, 1);
    },
    onChange(args) {
      const {id, checked} = args;
      const item = this.items[id].name;
      if (checked) {
        if (this.filter.filterCollection.indexOf(item) < 0) {
         this.filter.filterCollection.push(item);
        }
      } else {
        this.filter.filterCollection = this.filter.filterCollection.filter( i=> i != item);
      }
    },
  },
...

Here is the working CodeSandbox:

https://codesandbox.io/s/pensive-shadow-ygvzb?file=/src/components/Checkbox.vue

Sure, there are many ways to do it. If somebody has a nicer and shorter way to do it, please post your solution. It will be interesting to look at it.

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda