首页 > 解决方案 > Vue可组合范围问题

问题描述

我们将 Vue 2 与 Vue Composition 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在许多地方都可用,并且当darkModeref 的值发生变化时,突变只会触发一次。如何做到这一点?

标签: vue.jsvuejs2vue-componentvue-composition-api

解决方案


通过创建watch仅在需要时启动的可调用函数(即仅在应用程序中的某个位置)解决了该问题。

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

  const startWatch = () => {
    watch(darkMode, async (newDarkMode) => {
      await darkModeMutation()
    })
  }
  return { darkMode, startWatch }
}

可以在其中调用一次MainLayout.vue

// MainLayout.vue
import { defineComponent } from '@vue/composition-api'
import { useApplicationPreferences } from 'useApplicationPreferences'

export default defineComponent({
  setup() {
    const { startWatch } = useApplicationPreferences()
    startWatch()
  },
})

然后,所有其他组件可以darkMode根据需要简单地使用(获取/设置)引用,同时watch只运行一次。

// Settings.vue
import { defineComponent } from '@vue/composition-api'
import { useApplicationPreferences } from 'useApplicationPreferences'

export default defineComponent({
  setup() {
    const { darkMode } = useApplicationPreferences()

    return { darkMode }
  },
})

推荐阅读