Exploring the method of implementing a "template" with Vue 3 HeadlessUI TransitionRoot

I'm currently working on setting up a slot machine-style animation using Vue 3, TailwindCSS, and HeadlessUI. At the moment, I have a simple green square that slides in from the top and out from the bottom based on cycles within a for-loop triggered by clicking the "click to transition" button. The resetIsShowing() function is responsible for randomizing a sequential array (1-10). My objective is to display one of these 10 random numbers on the green square during each cycle. To achieve this, I modified the main div displaying the square to pass a random number during each cycle:

<div v-for="number in numbers" :key="number.id" class="h-full w-full rounded-md bg-green-500 shadow-lg">
 {{ number }}
</div>

However, when I add the list property to the above div, I encounter the following error:

The current component <TransitionChild /> is rendering a "template".
However we need to passthrough the following props:
  - ref

If I change "template" to "ref" in the TransitionRoot, I lose the desired slide down effect. How can I configure this setup so that numbers appear on the square with each cycle?

Below is the complete code:

<template>
    <div class="flex flex-col items-center py-16">
      <div class="h-72 w-72">
        <div class="flex justify-center items-center w-full h-full p-4 text-9xl rounded-md shadow-lg border-solid border-2 border-sky-500">
            <TransitionRoot
              appear
              :show="isShowing"
              as="template"
              enter="transition ease-in-out duration-300 transform"
              enter-from="-translate-y-full opacity-0"
              enter-to="translate-y-0 opacity-100"
              leave="transition ease-in-out duration-300 transform"
              leave-from="translate-y-0 opacity-100"
              leave-to="translate-y-full opacity-0"
            >

              <div v-for="number in numbers" :key="number.id" class="h-full w-full rounded-md bg-green-500 shadow-lg">
                {{ number }}
              </div>
    
            </TransitionRoot>
        </div>
      </div>
      <button
        @click="resetIsShowing"
        class="mt-8 flex transform items-center rounded-full bg-black bg-opacity-20 px-3 py-2 text-sm font-medium text-white transition hover:scale-105 hover:bg-opacity-30 focus:outline-none active:bg-opacity-40"
      >
        <svg viewBox="0 0 20 20" fill="none" class="h-5 w-5 opacity-70">
          <path
            d="M14.9497 14.9498C12.2161 17.6835 7.78392 17.6835 5.05025 14.9498C2.31658 12.2162 2.31658 7.784 5.05025 5.05033C7.78392 2.31666 12.2161 2.31666 14.9497 5.05033C15.5333 5.63385 15.9922 6.29475 16.3266 7M16.9497 2L17 7H16.3266M12 7L16.3266 7"
            stroke="currentColor"
            stroke-width="1.5"
          />
        </svg>
  
        <span class="ml-3">Click to transition</span>
      </button>
    </div>
  </template>
  
  <script setup>
  import { ref } from 'vue'
  import { TransitionRoot } from '@headlessui/vue'
  
  const isShowing = ref(true)
  const numbers = ref([])
  const numberArray = ref(Array.from({length: 10}, (e, i)=> i + 1))

  const sleep = (milliseconds) => {
    return new Promise(resolve => setTimeout(resolve, milliseconds))
  }
  
  async function resetIsShowing() {
    for (let i = 0; i < numberArray.value.length; i++) {
        const index = Math.floor(Math.random() * numberArray.value.length)
        await sleep(800)

        isShowing.value = false
  
        setTimeout(() => {
            isShowing.value = true
        }, 500)

        numbers.value = numberArray.value.filter(r => r === (index + 1))
    }
  }
  </script>

Answer â„–1

SOLVED

<template>
    <div class="flex flex-col items-center py-16">
      <div class="h-72 w-72">
        <div class="flex justify-center items-center w-full h-full p-4 rounded-md shadow-lg border-solid border-2 border-sky-500">
            <TransitionRoot
              appear
              :show="isShowing"
              as="template"
              enter="transition ease-in-out duration-[400ms]"
              enter-from="-translate-y-full opacity-0"
              enter-to="translate-y-0 opacity-100"
              leave="transition ease-in-out duration-[400ms]"
              leave-from="translate-y-0 opacity-100"
              leave-to="translate-y-full opacity-0"
            >

              <div class="h-full w-full rounded-md pt-16">
                <span v-if="numbers > 0" class="text-9xl">
                    {{ numbers }}
                </span>
              </div>
    
            </TransitionRoot>
        </div>
      </div>
      <button
        @click="resetIsShowing"
        class="mt-8 flex transform items-center rounded-full bg-black bg-opacity-20 px-3 py-2 text-sm font-medium text-white transition hover:scale-105 hover:bg-opacity-30 focus:outline-none active:bg-opacity-40"
      >
        <svg viewBox="0 0 20 20" fill="none" class="h-5 w-5 opacity-70">
          <path
            d="M14.9497 14.9498C12.2161 17.6835 7.78392 17.6835 5.05025 14.9498C2.31658 12.2162 2.31658 7.784 5.05025 5.05033C7.78392 2.31666 12.2161 2.31666 14.9497 5.05033C15.5333 5.63385 15.9922 6.29475 16.3266 7M16.9497 2L17 7H16.3266M12 7L16.3266 7"
            stroke="currentColor"
            stroke-width="1.5"
          />
        </svg>
  
        <span class="ml-3">Click to change</span>
      </button>
    </div>
  </template>
  
  <script setup>
  import { ref, watch } from 'vue'
  import { TransitionRoot } from '@headlessui/vue'
  
  const isShowing = ref(true)
  const numbers = ref([])
  const numberArray = ref(Array.from({length: 10}, (e, i)=> i + 1))

  const sleep = (milliseconds) => {
    return new Promise(resolve => setTimeout(resolve, milliseconds))
  }
  
  async function resetIsShowing() {
    for (let i = 0; i < numberArray.value.length; i++) {

        await sleep(1200)
        
        const index = Math.floor(Math.random() * numberArray.value.length)
        // const index = numberArray.value[i]
        
        numbers.value = numberArray.value.filter(r => r === (index + 1))[0]
        // numbers.value = numberArray.value.filter(r => r === (index))[0]
        
        console.log(numbers.value)
        
        isShowing.value = false
        
        setTimeout(() => {
            isShowing.value = true
        }, 500)
    }
  }
  </script>
  

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

Node.JS program unexpectedly logging MySQL results to console and exhibiting erratic behavior

Recently, I encountered a peculiar error while working with Node.JS MySQL. Strangely, I noticed that a result was being logged in the console without any corresponding code line instructing it to do so. Even more baffling was the fact that when I intention ...

Using Vuelidate with Vue 3, vue-class-component, and TypeScript combination

Is there anyone who has successfully implemented Vuelidate with Vue 3 using the Composition API? Although Vuelidate is still in alpha for Vue 3, I believe that if it works with the Composition API, there must be a way to make it work with classes as well. ...

The Apollo Client mutation input type is missing data

Currently, I am working with Apollo-client and facing an issue while making a mutation on the client. It seems that when I perform my mutation, the data being passed to the server becomes void. Below is my mutation type: type: recipeType, args:{ ...

What is the maximum number of groupings that can be created from a set of numbers within a

I'm trying to figure out how to handle a specific task, but I'm running into some obstacles. When adding numbers to clusters, a number is considered to belong to a cluster if its distance to at least one existing number in the cluster is within a ...

Barely populated React application following setup

I have been diving into React for quite some time now. However, today when I attempted to start a new project, it generated an almost empty project. My usual command create-react-app 'name-of-my-app' was used. It ran for a while and completed th ...

ESLint refuses to be turned off for a particular file

I am in the process of creating a Notes.ts file specifically for TypeScript notes. I require syntax highlighting but do not want to use eslint. How can I prevent eslint from running on my notes file? Directory Structure root/.eslintignore root/NestJS.ts r ...

Expanding the sidebar panel during a redirection

I am facing an issue with the expansion panels in my sidenav. I have successfully been able to track and set their open state as they are opened and closed. However, when a list item within the panel is clicked and redirects to another route, the panel c ...

We encountered a surprise issue: "/Users/username/package.json: Unexpected character \ in JSON at index 1" – this is not a duplicate question

While running the yarn command in various projects, I encountered the same error consistently. Error message: "An unexpected error occurred: "/Users/name/package.json: Unexpected token \ in JSON at position 1". Trace: SyntaxError: /Users/name/pack ...

There is an issue with the function of elem.autocomplete - it is not recognized

I'm new to Angular.JS and have been struggling for the past 6 hours. I've been working on reading data from an HTTP source and displaying it as an autocomplete feature on the view. Previously, the data was displayed in a select box, but I decide ...

What is the process of creating and verifying a Laravel random and temporary password?

I am seeking assistance in implementing a function that can generate an unpredictable password and subsequently verify if the user is utilizing the previously generated password. Your help and guidance are highly valued. Thank you sincerely! ...

Data table created with functional components is not refreshing when columns are added or removed, which are stored in the state as an array of objects

I’ve been working on setting up a datatable with a checkbox dropdown feature to add or remove columns from the table. Everything is functioning properly, except for one issue – the table is not refreshing unless I click on one of the header titles. At ...

NPM is searching for the package.json file within the user's directory

After completing my test suite, I encountered warnings when adding the test file to the npm scripts in the local package.json. The issue was that the package.json could not be located in the user directory. npm ERR! path C:\Users\chris\pack ...

Is there a way for me to access the response from the PHP file I'm calling with Ajax?

I am just starting to explore ajax and jquery, and I recently found a code online that I'm tweaking for my own use. However, I am struggling with how to handle responses from PHP in this context. The current setup involves ajax POSTing to a php page ...

Switching Story Tense on Facebook Open Graph

After creating a unique story for my facebook app, I discovered that when making a basic story post using the facebook js sdk, the resulting post is in past tense and depicts the object in singular form. For example, instead of saying: John is eating an a ...

Container slide-show fill error

I'm attempting to create a slide show with an overlapping caption that appears when hovering over the container or image. The image needs to fit exactly inside the container so no scroll bar is shown and the border radius is correct. I managed to achi ...

Utilizing Packery.js in AngularJS

Having some trouble trying to integrate Packery.js with my angularjs app. It seems like they are not working well together. I tried setting isInitLayout to false, but no luck. This is the (bootstrap 3) HTML code I am using: <div class="row" class="js ...

Implementing jQuery form validator post anti-SPAM verification?

I am facing what seems like a straightforward JavaScript issue, but my knowledge in this area is still limited. Following a successful implementation of basic anti-SPAM feature that asks the user to solve a simple math problem, how can I integrate jQuery& ...

Reload Popup Box

I am currently developing a website using Django and I am in need of a popup window that can display logging messages and automatically refresh itself every N seconds. In order to achieve this, I am utilizing the standard Python logger, JavaScript, and Daj ...

API request was blocked due to the CORS policy

As I work on developing a web app using Vue.js, users must log in to receive an API key. My post request to the API through axios includes two parameters - a name and a password. However, upon form submission, persistent errors keep appearing: OPTIONS htt ...

There is no index signature that accepts a parameter of type 'string' in the type '{ [key: string]: AbstractControl; }'

I'm currently tackling a challenge in my Angular project where I am creating a custom validator for a reactive form. However, I've encountered an error within the custom validators function that I am constructing. Below you will find the relevan ...