Home > Enterprise >  How to use Vue 3 reactive object outside Vue ecosystem
How to use Vue 3 reactive object outside Vue ecosystem

Time:03-23

I'm trying to pass global state created like this in micro front end applications. But the problem is that I have to "watch" for changes somehow in order to setState for example in a React app.

globalState.js

import { reactive } from 'vue'

const globalState = reactive({
  counter: 0
})

export default globalState

In Vue micro front ends im doing this and it is working fine

import { createApp } from 'vue'
import App from './App.vue'

export default (rootEl, globalState) => {
  const app = createApp(App)
  app.config.globalProperties.globalState = globalState
  app.mount(rootEl)
}

However in a React app I pass the reference correctly but when counter value changes I have to somehow detect it and call setState in order to rerender the change. The Question is how can I watch for changes of this reactive object reference outside Vue ecosystem.

CodePudding user response:

The Reactivity API is available as standalone libraries (separate from the vue package) that can be used outside the context of Vue.

@vue/reactivity includes reactive()/ref(). And @vue-reactivity/watch includes watch()/watchEffect().

For example, you could use a watchEffect (or watch) to log the new value of globalState.counter and display it in an element on the page:

// main.js
import { watchEffect } from '@vue-reactivity/watch'
import globalState from './globalState'

watchEffect(() => {
  console.log('counter', globalState.counter)
  document.querySelector('#count').innerHTML = globalState.counter
})
// globalState.js
import { reactive } from '@vue/reactivity'

const globalState = reactive({
  counter: 0
})

export default globalState

demo 1

In a React app, you could use a watch to log the new value of globalState.counter and then call a component's setState() to re-render the component:

import { useState, useEffect } from 'react'
import logo from './logo.svg'

import { watch } from '@vue-reactivity/watch'
import globalState from './globalState'
import GlobalCounterButton from './GlobalCounterButton'

function App() {
  const [count, setCount] = useState(0)

  useEffect(() => {
    const unwatch = watch(
      () => globalState.counter,
      (newValue, oldValue) => {
        if (newValue !== oldValue) {
          console.log('counter', newValue)
          setCount(newValue)
        }
      }
    )
    return () => unwatch()
  })

  return (
    <div>
      <GlobalCounterButton />
      <h2>count is: {count}</h2>
    </div>
  )
}

export default App

demo 2

  • Related