API — ссылка для композиции Vue 3 не работает в пакете npm

#vue.js #vuejs3 #ref #vue-composition-api #vue-reactivity

Вопрос:

У меня есть этот очень простой компонент Vue 3. Все работает нормально. value меняется каждые 0,5 с (консоль.вызывается журнал), и значение также меняется в браузере каждые 0,5 с.

 <template>
  <pre>value: {{ value }}</pre>
</template>

<script>
import { defineComponent, ref } from 'vue'

export default defineComponent({
  setup () {
    const value = ref(false)

    setInterval(() => {
      value.value = !value.value
      console.log('value changed to ', value.value)
    }, 500)

    return { value }
  }
})
</script>
 

И вот в чем моя проблема … Если я создам свой собственный пакет npm, скажем @my/package , со следующим кодом:

 import { ref } from 'vue'

const value = ref(false)

setInterval(() => {
  value.value = !value.value
  console.log('value changed to ', value.value)
}, 500)

export { value }
 

а затем я использую свой пакет в своем компоненте Vue 3 следующим образом:

 <template>
  <pre>value: {{ value }}</pre>
</template>

<script>
import { defineComponent } from 'vue'
import { value } from '@my/package'

export default defineComponent({
  setup () {
    return { value }
  }
})
</script>
 

тогда это не сработает. Точно сказано, console.log что регистрирует разные значения ( true или false ) каждые 0,5 с, но мой браузер по-прежнему отображает только начальное false значение.

В консоли нет ошибок. Просто кажется, что моя «реактивность» каким-то волшебным образом отказывается работать, если ref() она вызывается вне моего приложения Vue.

Это также не работает с reactive() и Vuex. Я хочу создать пакет npm, который будет предоставлять некоторые реактивные ссылки (созданные ref() ), и мое приложение Vue будет import использовать эти значения. Как сохранить реактивность при таком сценарии? Что я здесь упускаю?

РЕДАКТИРОВАТЬ: Я только что обнаружил, что он работает правильно, если я передаю ref из своего приложения Vue функцию пакета npm. Пример кода:

 import { defineComponent, ref } from 'vue'
import { createValue } from '@my/package'

export default defineComponent({
  setup () {
    // Notice Im passing the ref to the createValue function
    const value = createValue(ref)
    return { value }
  }
})
 

и мой @my/package код:

 export function createValue (ref) {
  const value = ref(false)

  setInterval(() => {
    value.value = !value.value
    console.log('value changed to ', value.value)
  }, 500)

  return value
}
 

Так что, похоже ref , что в моем приложении Vue и ref в моем пакете не одно и то же. Но почему?

ПРАВКА 2: Я сохранил свое ref в приложении Vue, как window.ref1 = ref , а затем я сохранил свое ref в пакете npm, как window.ref2 = ref . Когда я бегу window.ref1 === window.ref2 , это ложь. Таким образом, мое ref внутреннее приложение Vue ОТЛИЧАЕТСЯ от моего ref в пакете npm. Я импортирую оба с помощью следующего кода:

 import { ref } from 'vue'
 

Ответ №1:

Так что я нашел решение. Проблема заключалась в том, что я связал @my/package команду с помощью $ yarn link команды, поэтому у меня было две копии vue . Поэтому, когда я импортировал приложение ref в своем приложении Vue, оно отличалось от функции, ref импортированной в @my/package.

Самое простое решение здесь, вероятно, просто клонировать репозиторий Vue и запускать $ yarn link vue как в приложении Vue, так и в пакете.

Ответ №2:

Я рекомендую определить этот код внутри составной функции следующим образом :

 import { ref,onMounted } from 'vue'

export default function useValue(){
     const value = ref(false)

     onMounted(()=>{
       setInterval(() => {
         value.value = !value.value
         console.log('value changed to ', value.value)
       }, 500)
     })

    return {value}
}
 

затем используйте его, как :

 
<template>
  <pre>value: {{ value }}</pre>
</template>

<script>
import { defineComponent } from 'vue'
import useValue from '@my/package'

export default defineComponent({
  setup () {
  const { value} =useValue();

    return { value }
  }
})
</script>
 

пример

Комментарии:

1. Да, я знаю. Я просто старался сделать код как можно более простым. Но ваш пример не работает для меня 🙁 Он работает только в том случае, если я передаю ref вашу useValue() функцию следующим образом: useValue(ref) . Я отредактировал исходный пост.

2. это должно работать, просто импортируйте ссылку, как будто import { ref } from 'vue' не нужно передавать ее в качестве параметра

3. пожалуйста, проверьте этот пример codepen.io/boussadjra/pen/LYxGozg

4. Я проверил пример. Спасибо за помощь. Но это мне совсем не помогло. Я знаю, что твой код работает. Это в основном то же самое, что и мой первый показанный код. Проблема в том, что это не работает, когда я создаю свою ref ценность в пакете npm.

5. Я не понимаю, что вы подразумеваете под «построением». Но проблема, вероятно, в процессе моей разработки. Я использую пряжу и связываю этот пакет. Я запускаю «ссылку$ yarn» в корневой папке пакета. Затем я запускаю «$ yarn link @my/package» в корневой папке моего приложения Vue. Тогда я могу написать что-то вроде import { ... } from '@my/package' , и это сработает, но проблема в том, что у моего пакета npm есть собственная копия Vue. Так что мой ref в npm не такой, как ref в моем приложении Vue. Я пытаюсь понять, как это исправить.