Render checkboxes in For in loop and bind their Values in Vue JS

Stefan Bogdanescu

Founder & Senior Architect · 2026-06-29

Laravel Company

Render Checkboxes in For Loop and Bind Their Values in Vue JS: A Comprehensive Guide

Building dynamic filtering interfaces is a common requirement in modern web applications. When you need multiple criteria (like location, type, and price) to filter data, checkboxes are an excellent user interface solution. The challenge often lies not just in rendering them, but in managing their state efficiently—both capturing user input and setting the initial state based on URL parameters received from the server.

As a senior developer working with the Laravel and Vue stack, I frequently encounter this exact scenario. Let’s break down how to tackle rendering these dynamic filters, binding the values correctly, and handling pre-selected states using Vue.js.

The Challenge: Dynamic State Management in Vue

You are aiming to achieve two main goals:

  1. Capture User Input: When a user clicks a checkbox, Vue needs to instantly know which filter is active so you can send the correct data via an AJAX request (e.g., using Axios).
  2. Set Initial State: Based on URL parameters (like $location from your landing page), certain checkboxes should be checked automatically when the component loads.

Step 1: Structuring Your Data in Vue

First, you need a reactive structure to hold the list of available options and the currently selected filters.

<script setup>
import { ref, computed, watch } from 'vue';

// Simulate the data fetched from your API endpoint
const allLocations = ref([
  { id: 1, location: 'Candolim' },
  { id: 2, location: 'Tulum' },
  { id: 3, location: 'Alcudia' }
]);

// Reactive state to hold which locations are currently selected
const selectedLocations = ref([]);

// Function to handle checkbox changes
const toggleLocation = (locationId) => {
  const index = selectedLocations.value.indexOf(locationId);
  if (index > -1) {
    selectedLocations.value.splice(index, 1); // Deselect
  } else {
    selectedLocations.value.push(locationId); // Select
  }
};

// Function to handle initial state based on URL parameters
const initializeCheckboxes = (urlParams) => {
    if (urlParams.location) {
        // Check if the location from the URL exists in our list and select it
        const initialLocationId = allLocations.value.find(loc => loc.location === urlParams.location)?.id;
        if (initialLocationId) {
            selectedLocations.value.push(initialLocationId);
        }
    }
};

// Simulate parsing the URL parameters when the component mounts
const route = useRoute(); // Assuming you are using Vue Router
watch(() => route.query, (newQuery) => {
    initializeCheckboxes(newQuery);
}, { immediate: true });


</script>

<template>
  <div>
    <h2>Search by Location</h2>
    <p>Filter by Location:</p>
    
    <!-- Rendering the checkboxes in a loop -->
    <span v-for="item in allLocations" :key="item.id">
      <input 
        type="checkbox" 
        :value="item.location" 
        @change="toggleLocation(item.id)"
        :checked="selectedLocations.includes(item.id)"
      >
      <span class="checkbox-label">{{ item.location }}</span>
    </span>

    <hr>
    <p>Selected Locations: {{ selectedLocations.join(', ') }}</p>
  </div>
</template>

Step 2: Explanation and Best Practices

Capturing Values with v-model (or @change)

While you can use the :checked attribute to display the initial state, the most robust way to capture dynamic changes is by listening to the native DOM event using the @change handler. In the example above, we pass the unique item.id when the checkbox is toggled. This allows us to maintain a clean array (selectedLocations) of IDs that are currently active.

Setting Initial State from GET Request

The key to solving your second problem—automatically checking the $location checkbox upon page load—is leveraging Vue’s lifecycle hooks combined with route parameter access (if you are using Vue Router).

  1. Accessing Parameters: Use route.query (or equivalent context) within a watch or an onMounted hook to read the URL parameters passed by Laravel.
  2. Mapping State: Inside that logic, iterate through your available options and check if any option matches the incoming parameter value ($location). If it does, you push its corresponding ID into your selectedLocations array, which automatically updates the :checked attribute in the template via selectedLocations.includes(item.id).

This approach ensures that your component is fully reactive to the URL state, making data fetching much cleaner. This synergy between Laravel’s routing and Vue’s reactivity makes complex filter systems manageable. For deeper insights into structuring robust APIs that feed this data, exploring patterns found in frameworks like Laravel can be very helpful when designing your backend endpoints.

Conclusion

Rendering dynamic checkboxes and managing their state in Vue is fundamentally about reactive data binding. By separating the state management (the array of selected IDs) from the rendering logic, you create a scalable solution. For initial loading states driven by URL parameters, integrating route context with lifecycle hooks allows you to synchronize your frontend UI perfectly with the backend data provided by your Laravel application. Mastering this pattern will make building sophisticated filtering interfaces significantly smoother and more reliable.