Select All Checkboxes Using Composable Vue3

February 22nd, 2023

  • input checkbox: checkbox for selecting all checkboxes

  • checked if allEmailsSelected = true: that is true if the number of selected emails is equal to all emails

  • @click="toggleSelection"

    • if allEmailsSelected: => then deselect them (clear())

    • if all emails are not selected => the selectAll

1 <input type="checkbox"
2 @click="toggleSelection"
3 :checked="allEmailsSelected"
4 class="w-6 h-6 accent-pink-500"
5>
6 
7<script setup>
8 import { useEmailSelection } from "../composables/useEmailSelection"
9 // ...
10 const emailSelection = useEmailSelection()
11 
12 let props = defineProps({
13 emails: Array,
14 })
15 
16 let numberSelected = computed(() => emailSelection.selectedEmails.size)
17 let allEmailsSelected = computed(() => numberSelected.value == props.emails.length) // true or false
18 
19 function toggleSelection() {
20 if(allEmailsSelected.value) {
21 emailSelection.clear()
22 } else {
23 emailSelection.selectAll(props.emails)
24 }
25}

composables/useEmailSelection.js

  • create new Set selectedEmails

  • selectAll

  • clear()

  • toggle(email)

1import axios from 'axios';
2import { reactive } from 'vue';
3 
4// new Set outside of export: global state (updates in every component used)
5// if inside of export: state available only to 1 component, it wont update in other components
6let selectedEmails = reactive(new Set())
7 
8export const useEmailSelection = function(){
9 
10 // ...
11 
12 let selectAll = (allEmails) => {
13 allEmails.forEach(email => {
14 selectedEmails.add(email)
15 })
16 }
17 
18 let clear = () => {
19 selectedEmails.clear()
20 }
21 
22 let toggle = function(email) {
23 if(selectedEmails.has(email)) {
24 selectedEmails.delete(email)
25 } else {
26 selectedEmails.add(email)
27 }
28 }
29 
30 return {
31 selectedEmails,
32 selectAll,
33 clear,
34 toggle
35 }
36}
37 
38export default useEmailSelection

input for each email

1<table class="text-sm cursor-pointer border-collapse w-full">
2 <tbody>
3 <tr v-for="email in filteredEmails"
4 :key="email.id"
5 class="border-b border-t border-gray-700"
6 >
7 <td class="px-2 py-2">
8 <input type="checkbox"
9 class="w-6 h-6 accent-pink-500"
10 :checked="emailSelection.selectedEmail.has(email)"
11 @click="emailSelection.toggle(email)"
12 >
13 </td>
14 <td class="text-gray-500 px-2">{{ email.from }}</td>
15 <td class="font-semibold px-2 text-sm">{{ email.subject }}</td>
16 // ...

Related Posts