【发布时间】:2021-03-16 07:30:21
【问题描述】:
我们将 Vue 2 与 Vue 组合 API 一起使用,并且我们正在尝试创建一个可组合来公开应用程序首选项:
// useApplicationPreferences.ts
import { ref, watch } from '@vue/composition-api'
import { useSetDarkModeMutation, useViewerQuery } from 'src/graphql/generated/operations'
const darkMode = ref(false) // global scope
export const useApplicationPreferences = () => {
const { mutate: darkModeMutation } = useSetDarkModeMutation(() => ({
variables: {
darkMode: darkMode.value,
},
}))
watch(darkMode, async (newDarkMode) => {
console.log('darkMode: ', newDarkMode)
await darkModeMutation()
})
return { darkMode }
}
这段代码工作正常,但是当可组合用于同时渲染的两个组件中时,我们可以看到watch 已被触发两次。这很容易通过将watch 函数移动到全局范围(函数外)来解决。
但是,问题是我们不能使用darkModeMutation。这个 graphql 突变不能移动到函数之外的全局范围,如果我们这样做,页面甚至不会被渲染。
我们的目标是让darkMode 在许多地方都可用,并且当darkMode ref 的值发生变化时,突变只会触发一次。如何实现?
【问题讨论】:
-
导出
darkMode并在某处调用一次useApplicationPreferences怎么样?或者,既然 ref 应该是一个单例,不妨从根组件向下传递,并将其用作此可组合函数的参数。 -
使用可组合函数的整个想法是能够在许多地方重用它。附带说明一下,有许多
ref对象,而不仅仅是示例中的一个。 -
是的,明白了。但是像那些分散在不同地方的单身人士(而不是集中的来源),随着规模的扩大,维护起来会变得更加困难。此外,我在这个函数中看不到任何应该是可组合的——重复的手表告诉你这不是正确的模式。
-
我明白了。但是我们需要在
MainLayout.vue和Settings.vue中加载应用偏好。我们甚至可能有一个Statusbar.vue,我们需要相同的ref,比如DarkMode、language,......集中组合似乎是个好主意。 -
我仍然更喜欢 dependency injection 对于这个特定的用例。 Vuetify 内部似乎也使用了几乎相同的方法。
标签: vue.js vuejs2 vue-component vue-composition-api