Using a prop array as v-model in a Vue JS CheckBoxGroup implementation

Struggling to create a reusable CheckBoxGroup component with a prop array as v-model. I checked out the vuejs guide at https://v2.vuejs.org/v2/guide/forms.html#Checkbox which uses the v-model array in the data of the same component. However, this approach is limiting if I want to pass the v-model via props and have the ability to check some boxes from outside the component.

CheckBoxgroup.vue

<template>
  <div>
    <label v-for="day in allDays" :key="day">
      <input v-model="checkedDays" type="checkbox" :value="day" />
      <span>{{ day }}</span>
    </label>
    <div>Checked days: {{ checkedDays }}</div>
 </div>
</template>
<script lang="ts">
import Vue from 'vue'
import { Component, Prop } from 'vue-property-decorator'

@Component
export default class CheckBoxGroup extends Vue {
  @Prop() checkedDays!: string[]

  @Prop() allDays!: string[]
}
</script>

Index.vue

<template>
  <div>
    <checkbox-group :checked-days="checkedDays" :all-days="allDays" />
  </div>
</template>

<script lang="ts">
import { Vue, Component } from 'vue-property-decorator'
import CheckboxGroup from './checkBoxGroup.vue'

@Component({
  components: { CheckboxGroup },
})
export default class Index extends Vue {

  // This list would usually come from an API
  allDays = ['Monday', 'Tuesday', 'Wednesday']

  checkedDays = ['Monday']
}
</script>

The code works fine, but I am encountering the warning: [Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders... Is there a way around this issue? Any suggestions would be greatly appreciated.

Answer №1

Modifying the parent state directly from the children is not allowed in Vue.js, but you can trigger an event in the child component which will be handled by the parent to update the state. Here's an example:

Vue.component('check-box-group', {
  template: `
    <div>
      <label v-for="day in allDays" :key="day">
        <input 
          v-model="checkedDays" 
          :value="day" 
          @click="$emit('update-checked-days', { newCheckedDay: day })"
          type="checkbox" 
        />
        <span>{{ day }}</span>
      </label>
      <div>Checked days: {{ checkedDays }}</div>
    </div>
  `,
  props: {
    checkedDays: {
      type: Array,
      default: () => ([])
    },
    allDays: {
      type: Array,
      default: () => ([])
    },
  }
})

new Vue({
  el: "#app",
  data() {
    return {
      allDays: ['Monday', 'Tuesday', 'Wednesday'],
      checkedDays: ['Monday']
    }
  },
  methods: {
    HandleUpdateCheckedDays({newCheckedDay}) {
      const indexOfCheckedDay = this.checkedDays.findIndex(checkedDay => checkedDay === newCheckedDay)

      if (indexOfCheckedDay === -1) { // if not exists then add to checkedDays
        this.checkedDays.push(newCheckedDay)
      } else {
        this.checkedDays = this.checkedDays.filter((_, i) => i !== indexOfCheckedDay)
      }
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script>

<div id="app">
  <check-box-group 
    :checked-days="checkedDays" 
    :all-days="allDays" 
    @update-checked-days="HandleUpdateCheckedDays"
  />
</div>

note: keep in mind that TS class composition is no longer supported.

Answer №2

Appreciate the input, I was able to successfully resolve it using v-model too, but it felt a bit makeshift and less versatile when dealing with externally injected data Models. Therefore, I've decided to adopt your approach.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

I am struggling to display an array of objects retrieved from the server in the UI using AngularJS

I am receiving an array of objects as a JSON from the server. When I try to access my service URI from HTML, I encounter the following array in my console: "angular.js:13920 Error: [$resource:badcfg] http://errors.angularjs.org/1.5.8/$resource/badcfg?p0= ...

What is the best way to update an array within an object using Redux?

I am currently working on a code for redux that involves an array. const initialState = [{ id: '1', title: '', description: '' }]; My goal is to update the array to contain two objects like this: [{ id: '1', title: ...

Can a direct link to a Redis server be established through a web browser?

Can a connection be established with a redis server directly from the browser? In node, you can create a TCP connection using var client = net.connect(port, host);. I'm curious if it's possible to achieve the same in the browser either through Br ...

Managing the clearing of a view component in React or Vue.js

In my project, I have a container component that handles all the business logic, ajax requests, and data management. This container component has child components to which it passes data and methods as props. For example, there is a "CommentForm" compone ...

Unleashing the Power of Vuejs: Setting Values for Select Options

I have a specific requirement in my Vue application where I need to extract values from an XLS file and assign them to options within a select dropdown. Here is what I currently have: <tr v-for="header in fileHeaders" :key="header"&g ...

"Could you please help me understand the process of receiving a JSON in an Express

When working with React, I encountered an issue where the JSON data sent to me from the front-end is in a strange format (an object with the data as a string). I am unsure how to convert it back into the object type. This is what I send: const data = { ...

Transform the appearance of buttons within AppBar using Material UI React

Embarking on a new project using React and Node JS has led me into the battle with Material UI. My current challenge is customizing the style of AppBar items, particularly the Buttons. Here's what I have in my "Menu" component: const Menu = () => ...

Is there a way to place two input fields from different forms side by side on the same line?

Here are two forms extracted from an html page: <form method="get" action="search/s" id="number"> <div style="text-align: center;"> <input type="text" id="regNo" name="regNo" size="30" maxLength="50" > or ...

Develop a "Read More" button using Angular and JavaScript

I am in search of all tags with the class containtText. I want to retrieve those tags which have a value consisting of more than 300 characters and then use continue for the value. However, when I implement this code: <div class=" col-md-12 col-xl-12 c ...

What could be causing the delay in response times from these unpredictable APIs within the Express server?

We are currently experiencing performance issues with our Express.js server and MongoDB database. Randomly, some API requests are taking too long to respond or timing out throughout the day. Our application is in production, hosted on two AWS instances wit ...

The submit button remains unresponsive, yet upon removing its JavaScript code, it functions smoothly

This is the content of my index.html file. It contains JavaScript code. However, there seems to be a problem with the JavaScript validation as the Submit button does not perform any action when clicked. Surprisingly, when I remove the JavaScript code, the ...

Updating nested objects: A guide on how to effectively modify complex

I am trying to utilize the $push method in order to insert an object into a nested array, but I am struggling to dynamically access the correct object inside the array. Allow me to provide a clearer explanation by showcasing the code. Here is my Schema: ...

transferring data to Amazon Web Services using Angular framework

I'm currently facing an issue while trying to send a file to an AWS server using an Angular dropzone. I have my AWS credentials ready, but I am unsure of how to properly make the request. Every time I attempt to drop the file into the dropzone, I kee ...

Modifying paragraph content with JavaScript based on selected radio button values and troubleshooting the onclick event not triggering

I am working on implementing a language selection feature on my website where users can choose between English and Spanish. The idea is to have two radio buttons, one for each language, and a button. When the button is clicked, the text of the paragraphs s ...

There seems to be an issue with declaring Gulp Open

Here is the code snippet for my `open.js` task: import gulp from 'gulp'; import gulpOpen from 'gulp-open'; gulp.task('open', () => { // doesn't work with `function()` either. const options = { uri: 'local ...

Analyzing Data for Distributed / External Pages

Our team is currently exploring options for tracking metrics on content we produce for external pages. We are considering various approaches such as creating our own JavaScript, using a tracking pixel, or adapting Google Analytics to fit our needs. We wou ...

The local variable within the Angular constructor is not initialized until the ngOnInit() function is invoked

I am encountering difficulties with making backend calls from Angular. In my component, I am fetching the "category" parameter from the URL as shown below: export class ProductsComponent{ productList = [] category = "" $params; $products ...

Which option's value was recently removed from the fetch command?

I created a function to handle duplicate selections in a select element. It is functioning properly, but I noticed that when I remove an option from the select, my array remains unchanged. If I remove an option, I want my code to detect the value of that ...

Error: The SpringBoot API returned a SyntaxError because an unexpected token < was found at the beginning of the JSON response

I am currently following a tutorial on Spring Boot React CRUD operations which can be found here. However, I have encountered an issue when trying to fetch JSON data from the REST API and display it in my project. Despite following the steps outlined in th ...

Access and retrieve real-time JavaScript variables directly from a website

Question: I am curious about the possibility of accessing JavaScript variables on a website from C#. Since the scripts are on the client side, is it possible to read their values live through C#? Any assistance or guidance on this matter would be greatly ...