如何在 Vue 生态系统之外使用 Vue 3 反应对象

How to use Vue 3 reactive object outside Vue ecosystem

我正在尝试在微前端应用程序中传递这样创建的全局状态。但问题是我必须以某种方式“观察”变化,以便在 React 应用程序中设置状态。

globalState.js

import { reactive } from 'vue'

const globalState = reactive({
  counter: 0
})

export default globalState

我在 Vue 微前端中这样做并且工作正常

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)
}

然而,在 React 应用程序中,我正确地传递了引用,但是当计数器值发生变化时,我必须以某种方式检测它并调用 setState 以重新呈现更改。问题是我如何在 Vue 生态系统之外观察这个反应对象引用的变化。

Reactivity API 可以作为独立的库(与 vue 包分开)使用,可以在 Vue 上下文之外使用。

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

例如,您可以使用 watchEffect(或 watch)来记录 globalState.counter 的新值并将其显示在页面的元素中:

// 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

在 React 应用程序中,您可以使用 watch 来记录 globalState.counter 的新值,然后调用组件的 setState() 到 re-render 组件:

import { useState, useEffect } from 'react'
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