vuejs3composable

Can a VUE 3 composable contain more than a single exported function?


I am trying to re-write some functions as VUE Composables and it looks to me like only one exported function is available for a single 'composable.ts' file. Is that true, or is there a way to export multiple functions from a single composable?


Solution

  • The way that Vue composables are (and should be used) is that they are a single function which encapsulates and reuses stateful logic. You have freedom to do whatever-Vue-stuff you want within and from that single export you can return multiple things: states, methods, computeds, etc.

    Note: Code snippets are from this article.

    Paradigm A - One composable returning multiple inner parts

    Example:

    useCounter.js

    import { ref } from "vue";
    
    export function useCounter() {
      const count = ref(0);
    
      function increment() {
        count.value++;
      }
    
      function decrement() {
        count.value--;
      }
    
      return { count, increment, decrement };
    }
    

    Usage:

    anyComponent.vue

    import { useCounter } from './useCounter';
    const { count, increment, decrement } = useCounter();
    
    increment();
    decrement();
    console.log(count);
    

    Paradigm B - A parent composable exporting multiple imported composables

    Example:

    useTimerCounter.js

    import { useCounter } from "./useCounter";
    import { useTimer } from "./useTimer";
    
    export default {
      setup() {
        const { count, increment, decrement } = useCounter();
        const { time, start, stop } = useTimer();
    
        return { count, increment, decrement, time, start, stop };
      },
    };
    

    Usage:

    anyComponent.vue

    import useTimerCounter from './useTimerCounter';
    const { count, increment, decrement, time, start, stop } = useTimerCounter();
    
    increment();
    decrement();
    console.log(count);
    
    start();
    stop();
    console.log(time);
    

    Side note: Consider whether you actually need a Vue composable. If your logic is stateless and/or doesn't need any Vue features, then perhaps regular JS "helper" functions/classes are more efficient & portable than a Vue composable.