How do View Composables work – Explanation with Examples of Code

by SkillAiNest

Vue Composables is a very helpful tool when developing Vue applications. They provide developers an easy way to reuse logic in our applications. In addition to allowing “Stateless” logic (things like formatting or routine calculation), composables also give us the ability to reuse state logic throughout the app.

Before diving into the tutorial below, I would like to say that there are documents for Wu Really Nice Page on Compositable The basics really explain well and you will find 90 % of the way there. I am writing this article because I think the examples in the documents can be a little deeper to tell how things can work within a composingable. I will repeat some information from the documents, but I will also provide an example of a more complex composing composing.

Here’s what we will cover is:

Why use composables?

Composites allow you to reuse state logic in your apps. Whenever there is logic that is used in more than two places, we usually want to draw this logic into its own function. Most of the time, this logic is considered “state lace”, which means it takes input and returns out. The documents mention the date of the date, but it may include anything like currency calculations or string verification.

In modern web applications, there are often pieces of logic that need to be managed over time. Within a common component, we have the ability to adopt the application in terms of the “state” of various variables within the ingredient. Sometimes they are reuse logic, or at least pieces of this logic, throughout the app.

For example, in the e -commerce application, you may have the logic to increase and reduce the amount of a product that someone is adding to his cart. This logic can be used on the product page and inside the automatic.

The appearance of these two places will be different, so reusing a complete component will not make sense-but we still want to maintain the code so that the code can be maintained. This is the place where composers come.

(It is worth noting that not everything needs to be composed. The logic that is used in only one component should not be made in the composable until one is necessary.)

Easy Compositable Examples

Let’s take a look at a simple counter example. Here is some code for a very easy Counter Ingredient

 

The production of this component will look like this:

8c39759c-6FD9-4FCF-ABDF-F67E672C172F

It does a great job, but if we remove the need for the same counter logic in another component with a completely different shape and feeling, we will repeat the logic. We can remove the logic into a composingable and access the same state logic wherever we need.


import { ref } from 'vue'
import type { Ref } from 'vue'

export default function useCounter(): Readonly<{
  count: Ref<number>
  increment: () => void
  decrement: () => void
}> {
  const count: Ref<number> = ref(0)
  const increment = () => {
    count.value++
  }
  const decrement = () => {
    count.value--
  }
  return { count, increment, decrement }
}

Then we update the script tag in the component to use the composables:

 

We can now use this logic in a number of ingredients in the app.

D90d000e-F309-4B22-9530-8E4614b450C

You’ll see that only logic has been copied and each component still has its own copy count The use of state composables does not mean that the state is shared in components, only the logic of the state.

Complicated composables

In Vue Documents, they give an example of using a compose to recover ASYnc data. I have two problems with the example I have given. Most importantly, real -world applications are not a mistake to deal with the error. It is understandable that they just want to use the composingables directly. But I wanted to show another realistic implementation.

For the Util Function fetch

Before you go to the composer, we need to set up a utilized function for this fetch API. The reason for this is that we want to make sure that if every request fails, it throws a mistake. fetch If the application responds as an error, API does not throw any mistake. We have to check response.ok To confirm the status and then throw the mistake if necessary.


export async function handleFetch(url: string, options: RequestInit = {}): Promise<Response> {
  const res = await fetch(url, options)
  if (!res.ok) {
    const err = await res.text()
    throw new Error(err)
  }
  return res
}

UseasyNcstate Compositable

When working with ASYNC State, requests may be in a few different states:

  • Below

  • Solution

  • Rejection

In addition to these states, we want to track data or error that will be returned from the request.


import { shallowRef } from 'vue'
import type { Ref } from 'vue'


export type AsyncState = {
  data: Refnull>
  error: Ref<Error | null>
  isPending: Ref<boolean>
  isResolved: Ref<boolean>
  isRejected: Ref<boolean>
}

export default function useAsyncState<T>(promise: Promise): AsyncState<T> {
  
  
  const data = shallowRefnull>(null)
  const error = shallowRef<Error | null>(null)
  const isPending = shallowRef(false)
  const isResolved = shallowRef(false)
  const isRejected = shallowRef(false)

  data.value = null
  error.value = null
  isPending.value = true
  isRejected.value = false
  isResolved.value = false

  promise.then((result) => {
    data.value = result
    isPending.value = false
    isResolved.value = true
  }).catch(err => {
    error.value = err
    isPending.value = false
    isRejected.value = true
  })

  return { data, error, isPending, isResolved, isRejected }
}

It has some other clear qualities for different states rather than relying on values data And error. You will also see that this compose is promised instead of a URL wire like the DOCS Show. There will be different types of reactions in different perspectives and I wanted to be able to handle those out of this composing.

Used in a component

I have set a closing point that will wait successfully or for a random number of seconds before responding successfully. My component is calling this closing point using the composable and using composable data to update the template.

304b8c08-5277-4243-B621-70A7C19edCFD

With such a disturbed condition:

7d0c6923-85b9-4971-8f69-D127FA6C1F4

You can see a working example https://undonseding-composables.pages.dev/.

Explaining and understanding it to make it a bit easier l i, i’m breaking it

Here we have a way, getRandomResponse Which calls a closing point and returns the promise. Then this promise has been transferred to him useAsyncState While handleMakeRequest Called. Who puts the entire return in the cost randomResponseData Reef, which we can then use inside the template.

Instead of displaying the full template, I’ll just show part of it.

Here you can see that two different buttons are used in terms of state. I am using a separate button element to indicate a “loading” condition, but in practice you can use composable properties to set disabled Change the button property and text.

        <button
          v-if="
            !randomResponseData?.isPending &&
            !randomResponseData?.error &&
            !randomResponseData?.data
          "
          class="px-6 py-3 bg-blue-600 hover:bg-blue-700 text-white font-medium rounded-lg transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
          @click="handleMakeRequest"
        >
          Make Request
        button>

        
        <button
          v-if="randomResponseData?.isPending"
          disabled
          class="px-6 py-3 bg-blue-600 text-white font-medium rounded-lg opacity-75 cursor-not-allowed flex items-center mx-auto"
        >
          <svg
            class="animate-spin -ml-1 mr-3 h-5 w-5 text-white"
            xmlns="
            fill="none"
            viewBox="0 0 24 24"
          >
            <circle
              class="opacity-25"
              cx="12"
              cy="12"
              r="10"
              stroke="currentColor"
              stroke-width="4"
            >circle>
            <path
              class="opacity-75"
              fill="currentColor"
              d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
            >path>
          svg>
          Loading...
        button>

Here are some rows from the table:

<tr class="divide-x divide-gray-200">
  <td class="py-4 pr-4 pl-4 text-sm font-medium whitespace-nowrap text-gray-900 sm:pl-0">
    isPending
  td>
  <td
    class="p-4 text-sm whitespace-nowrap text-gray-500"
    :class="randomResponseData?.isPending ? 'bg-blue-500' : 'bg-gray-300'"
  >td>
  <td class="p-4 text-sm whitespace-nowrap text-gray-500">
    {{ randomResponseData?.isPending }}
  td>
tr>

<tr class="divide-x divide-gray-200">
  <td class="py-4 pr-4 pl-4 text-sm font-medium whitespace-nowrap text-gray-900 sm:pl-0">
    data
  td>
  <td
    class="p-4 text-sm whitespace-nowrap text-gray-500"
    :class="randomResponseData?.data ? 'bg-green-500' : 'bg-gray-300'"
  >td>
  <td class="p-4 text-sm whitespace-nowrap text-gray-500">
    {{ unref(randomResponseData?.data)?.msg }}
  td>
tr>

In them tr Tags, you can see the template offering different things in terms of the state coming from the composing.

Looking more fully on the code L you, you can visit Gut Hub Rippo. You can also see how a combination of composables, Vivos, similar functionality handles:

In the next article, I will dive into their implementation.

Conclusion

Composeable Vue 3 has an incredibly useful tool. As the projects grow in size and scope, knowing how and when composables are to use can improve the care of the project for a long time.

The key is indicating that when you have a state logic that needs to be reused in the ingredients, then remove it in a well -made composingable that handles the edge matters properly.

More real examples of the world Lou You can check it out Vueuse Library And Repo.

You may also like

Leave a Comment

At Skillainest, we believe the future belongs to those who embrace AI, upgrade their skills, and stay ahead of the curve.

Get latest news

Subscribe my Newsletter for new blog posts, tips & new photos. Let's stay updated!

@2025 Skillainest.Designed and Developed by Pro