在 Vue 3 的插件中创建全局计算 属性

Create a global computed property in a plugin in Vue 3

我正在尝试从 Vue 3 插件中创建一个全局计算 属性,以便我的 属性 可以在任何组件中反应使用。我正在使用 standard Vue 3 模式:

app.config.globalProperties.$foo = ...

这非常适合让我从任何组件访问 this.$foo。但是,我还想在 this.$fooset 时触发行为。但是当我尝试使它成为可设置的计算 属性 时,就像这样—

app.config.globalProperties.$foo = computed({
  get: () => ...
  set: () => ...
})

—它的行为不像计算的 属性:如果我从组件 运行 this.$foo = 'bar',它只是覆盖 属性,而不会触发计算的setter。 (在没有 setter 的计算上测试它,属性 也被简单地覆盖,Vue 通常会在其中发出警告。)

如何使用 setter 进行全局计算?关于全局属性(或 Vue 3 组合中的计算属性 API)应该如何工作,我在这里遗漏了什么吗?

computed()returns一个ref,所以它的值必须通过.value属性来访问。直接设置 $foo 只会覆盖对某个新值的引用,而不是修改 computed 引用的值:

this.$foo = 'bar'        // ❌ overwrites the computed ref
this.$foo.value = 'bar'  // ✅ sets computed ref's value; triggers setter

您可能需要反应性,而带有 getter/setter 的 computed ref 需要为此使用另一个 ref

// main.js
import { computed, ref } from 'vue'
⋮
let foo = ref(123)
app.config.globalProperties.$foo = computed({
  get: () => foo.value,
  set: value => foo.value = value,
})
// MyComponent.vue
export default {
  methods: {
    logFoo() {
      console.log(this.$foo.value) // => 123
    },
    updateFoo() {
      this.$foo.value++
    }
  }
}

demo