0
0
VueHow-ToBeginner · 3 min read

How to Share State Using Composable in Vue 3

To share state using a composable in Vue 3, create a function that returns reactive state using ref or reactive. Import and call this composable in multiple components to access and update the shared state reactively.
📐

Syntax

A composable is a function that encapsulates reactive state and logic. It typically uses Vue's ref or reactive to create state, and returns it so components can use it.

Example parts:

  • import { ref } from 'vue': imports reactive helpers
  • const state = ref(initialValue): creates reactive state
  • return { state }: exposes state to components
javascript
import { ref } from 'vue'

export function useSharedState() {
  const count = ref(0) // reactive state

  function increment() {
    count.value++
  }

  return { count, increment }
}
💻

Example

This example shows two components sharing the same count state using a composable. Incrementing in one updates the other automatically.

javascript
import { createApp } from 'vue'

// Shared state outside composable to ensure singleton
import { ref } from 'vue'
const count = ref(0)

function useSharedState() {
  function increment() {
    count.value++
  }
  return { count, increment }
}

// Component A
const ComponentA = {
  setup() {
    const { count, increment } = useSharedState()
    return { count, increment }
  },
  template: `<div>
    <h2>Component A</h2>
    <p>Count: {{ count }}</p>
    <button @click="increment">Increment</button>
  </div>`
}

// Component B
const ComponentB = {
  setup() {
    const { count } = useSharedState()
    return { count }
  },
  template: `<div>
    <h2>Component B</h2>
    <p>Count: {{ count }}</p>
  </div>`
}

// Root app
createApp({
  components: { ComponentA, ComponentB },
  template: `<div>
    <ComponentA />
    <ComponentB />
  </div>`
}).mount('#app')
Output
<div> <div> <h2>Component A</h2> <p>Count: 0</p> <button>Increment</button> </div> <div> <h2>Component B</h2> <p>Count: 0</p> </div> </div>
⚠️

Common Pitfalls

Not sharing the same instance: If you call the composable function inside each component without preserving the state outside, each component gets its own separate state.

Fix: Define the state outside the composable function so it is shared across calls.

javascript
import { ref } from 'vue'

// Wrong: state inside function creates new instance each call
export function useWrongSharedState() {
  const count = ref(0) // new count every call
  return { count }
}

// Right: state outside function shares same instance
const count = ref(0)
export function useRightSharedState() {
  return { count }
}
📊

Quick Reference

  • Define reactive state (ref or reactive) outside composable function to share it.
  • Return state and methods from composable for components to use.
  • Import and call composable in any component to access shared state.
  • Use composables to keep logic reusable and state centralized.

Key Takeaways

Place reactive state outside the composable function to share it across components.
Return reactive state and functions from the composable for easy reuse.
Import and call the composable in any component to access shared state.
Composable functions help keep state and logic organized and reusable.