graydam
graydam

Reputation: 269

How to use Vue Composition API as Global State Across Components?

So I tried to use Vue Composition API as global state. As example, I created file called useLoading.js as loading flag.

useLoading.js

import { reactive, toRefs } from '@vue/composition-api'

export default () => {
  const state = reactive({
    isLoading: false
  })

  const setIsLoading = (loading) => {
    state.isLoading = loading
  }

  return {
    ...toRefs(state),
    setIsLoading
  }
}

Then I created component A in which it will call the setIsLoading when the button is clicked

ComponentA.vue

<template>
  <div @click="showLoading" />
</template>

<script>
import useLoading from '@/composable/useLoading'

export default {
  setup () {
    const { setIsLoading } = useLoading()

    function showLoading () {
      setIsLoading(true)
    }

    return {
      showLoading
    }
  }
}
</script>

I also have component B in which it will use to render a <div> when the value of isLoading is true

ComponentB.vue

<template>
  <div v-if="isLoading" />
</template>

<script>
import useLoading from '@/composable/useLoading'

export default {
  setup () {
    const { isLoading } = useLoading()

    return {
      isLoading: isLoading
    }
  }
}
</script>

Yet the value of isLoading in ComponentB.vue was not change (not reactive). But the value did change when I called in in ComponentA.vue

I feel like there is something wrong with my implementation in using Composition API as global state. Can anyone help?

Thank you

Upvotes: 9

Views: 6713

Answers (1)

graydam
graydam

Reputation: 269

UPDATE

Just found out I have to exclude the state from the export function, If I include it inside the export function, it will create other states if it is called in a different place. So the state will not sync between components.

import { reactive, toRefs } from '@vue/composition-api'

const state = reactive({
    isLoading: false
})

export default () => {

  const setIsLoading = (loading) => {
    state.isLoading = loading
  }

  return {
    ...toRefs(state),
    setIsLoading
  }
}

Upvotes: 11

Related Questions