skip to Main Content

I’m attempting to use the Tailwind headlessui <Switch> component in a Vue3/InertiaJS app, and when I put it in my component as it is in the docs, using an enabled ref() variable for the value, it works fine. However, when I bind it via v-model to a useForm() value like so:

<script setup>
const form = useForm({
   enabled: false
    ...
})
</script>

<template>
<Switch
    v-model="form.enabled"
    ...
>
</template>

it doesn’t work. Instead, the button doesn’t work at all, and there are no console errors. I have many other fields in the same form that work fine with the form fields, so its’ just this one. The only difference I can see is that the examples use ref(), and useForm() uses reactive(), but I can’t see why that would make a difference.

2

Answers


  1. Chosen as BEST ANSWER

    Credit to the answer above by @mikalai-parakhnevich, I was missing the form reference for the :class binding. I did not need the @update:modelValue line.

    <SwitchGroup>
        <Switch
            v-model="form.enabled"
            :class="form.enabled ? 'bg-gray-200' : 'bg-white'"
            class="relative inline-flex h-6 w-11 items-center rounded-full"
        >
        <span class="sr-only">Me label</span>
        <span
            :class="form.enabled ? 'translate-x-6' : 'translate-x-1'"
            class="inline-block h-4 w-4 transform rounded-full bg-indigo-600 transition"
        />
        </Switch>
        <SwitchLabel class="mx-4">My label</SwitchLabel>                   </SwitchGroup>
    

  2. At first glance, there is no error in your description of the problem. I’ll give an approximate usage algorithm, maybe it will help

    1. Install inertiajs for vue

      npm install @inertiajs/inertia-vue3
      yarn add @inertiajs/inertia-vue3
      
    2. Import useForm from inertiajs in your component

      import { useForm } from '@inertiajs/inertia-vue3';
      
    3. Create a form object:

      const form = useForm({
        enabled: null,
        ...
      })
      
    4. We use it in the component template as:

      import { Switch } from "@headlessui/vue";
      ...
      <Switch
         v-model="form.enabled"
      

    Full code:

    <template>
      <div class="p-6">
        <Switch
          v-model="form.enabled"
          @update:modelValue="test"
          :class="form.enabled ? 'bg-blue-600' : 'bg-gray-200'"
          class="relative inline-flex h-6 w-11 items-center rounded-full"
        >
          <span class="sr-only">Enable notifications</span>
          <span
            :class="form.enabled ? 'translate-x-6' : 'translate-x-1'"
            class="inline-block h-4 w-4 transform rounded-full bg-white transition"
          />
        </Switch>
      </div>
    </template>
    
    <script setup lang="ts">
    import { useForm } from "@inertiajs/inertia-vue3";
    
    import { Switch } from "@headlessui/vue";
    
    const form = useForm({
      enabled: false,
    });
    </script>
    

    and an example in action

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search