Как вызвать композиционную функцию из другой композиции в VueJS - PullRequest
0 голосов
/ 30 мая 2020

Я экспериментировал с новым API-интерфейсом композиции в VueJS и не знаю, как решить проблему. Мне нужен совет, как правильно реализовать решение. Это не было проблемой, когда все было основано на vuex, поскольку вы можете без проблем отправить действие другому модулю. Однако я изо всех сил пытаюсь найти решение для реализации композиции.

Проблема:

  1. Компонент вызывает CompositionA функция.
  2. CompositionA запускает функцию входа в систему.
  3. В ответ на успешный / неудачный вход в систему CompositionA Я хотел бы вызвать функцию CompositionB . (CompositionB содержит данные и logi c для отображения закусочной, используемой на сайте)

Проблема в том, что необходимо внедрить зависимость закусочной панели в каждый компонент, а не создавать ее экземпляр / монтируется из CompositionA . Текущее решение таково:

Component.vue:

// template calls login(credentials) method
import { useCompositionA } from '@/compositions/compositionA'
import { useCompositionB } from '@/compositions/compositionB'
export default {
  name: 'Component',
  setup(props, context) {
    const { login } = useCompositionA(props, context, useCompositionB(props, context))
    return {
      login
    }
  },
}

compositionA.js:

export const useAuth = (props, context, snack) => {
  const login = async (credentials) => {
    try {
      return await loginWithEmailPassword(credentials)
      snack.show({text: 'Welcome back!'})
    } catch (err) {
      snack.show({text: 'Failed to login'})
    }
  }
  return { login }
}


compositionB.js:

export const useSnack = (props, context) => {
  const snack = reactive({
    color: 'success',
    text: null,
    timeout: 6000,
    visible: true,
  })

  const snackRefs = toRefs(snack)

  const show = ({ text, timeout, color }) => {
    snackRefs.text.value = text
    snackRefs.timeout.value = timeout || 6000
    snackRefs.color.value = color || 'success'
    snackRefs.visible.value = true
  }
  return { 
    ...snackRefs,
    show
  }
}

Было бы неплохо, если бы существовало что-то вроде ниже, но я обнаружил, что свойства не реагируют на CompositionB , если оно используется из CompositionA (метод вызывается, но закусочная не отображается). Насколько я понимаю, Vue не вводит CompositionB в Component , поэтому я просто запускаю другой экземпляр CompositionB внутри CompositionA . Что я делаю не так? Какое здесь подходящее решение?

compositionA.js (not working):

import { useCompositionB } from '@/compositions/compositionB'
export const useAuth = (props, context) => {
  const login = async (credentials) => {
    const { show } = useCompositionB()
    try {
      return await loginWithEmailPassword(credentials)
      show({text: 'Welcome back!'})
    } catch (err) {
      show({text: 'Failed to login'})
    }
  }
  return { login }
}

Заранее спасибо,

1 Ответ

0 голосов
/ 30 мая 2020

Как и ожидалось, это произошло из-за того, что Component ссылается на свою собственную локальную копию CompositionB *. На самом деле решение состоит в том, чтобы вывести состояние ваших композиций в глобальную область в соответствии с:

https://vueschool.io/articles/vuejs-tutorials/state-management-with-composition-api/

Примерно так:

compositionB.js:

const snack = reactive({
  color: 'success',
  text: null,
  timeout: 6000,
  visible: true,
})
export const useSnack = (props, context) => {

  const snackRefs = toRefs(snack)

  const show = ({ text, timeout, color }) => {
    snackRefs.text.value = text
    snackRefs.timeout.value = timeout || 6000
    snackRefs.color.value = color || 'success'
    snackRefs.visible.value = true
  }
  return { 
    ...snackRefs,
    show
  }
}

Работает как шарм.

Единственным предостережением, которое я обнаружил изначально, была ошибка API-композиции:

Uncaught Error: [vue-composition-api] must call Vue.use(plugin) before using any function.

согласно решению здесь:

Неперехваченная ошибка: [vue -composition-api] должен вызвать Vue .use (plugin) перед использованием любой функции

Думаю, с выходом vue3 проблем не будет. Надеюсь, это кому-то поможет.

...