0
votes

I have this very simple Vue 3 component. Everything works fine. value changes every 0.5s (console.log is being called) and the value changes in browser every 0.5s as well.

<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>

And here is my problem ... If I create my own npm package, let's say @my/package with the following code:

import { ref } from 'vue'

const value = ref(false)

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

export { value }

and then I use my package in my Vue 3 component like this:

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

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

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

then it doesn't work. Exactly said, the console.log logs the different values (true or false) every 0.5s but my browser still renders only the initial false value.

There are no errors in console. It just seems like my "reactivity" somehow magically refuse to work if the ref() is called outside of my Vue app.

This also doesn't work with reactive() and Vuex. I want to create a npm package that will expose some reactive references (created by ref()) and my Vue app will import these values. How to keep the reactivity in such a scenario? What am I missing here?

EDIT: I've just discovered that it DOES work correctly if I pass the ref from my Vue application to the npm package function. Example code:

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

and my @my/package code:

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

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

  return value
}

So it seems like the ref in my Vue app and the ref in my package aren't the same. But why?

EDIT 2: I saved my ref in the Vue app like window.ref1 = ref and then I saved my ref in the npm package like window.ref2 = ref. When I run window.ref1 === window.ref2 it is false. So my ref inside Vue app is NOT the same like my ref in the npm package. I import both with the following code:

import { ref } from 'vue'
2

2 Answers

1
votes

So I found the solution. The problem was that I linked the @my/package using the $ yarn link command so I had two copies of vue. So when I imported the ref within my Vue app, it was the different function than the ref imported within @my/package.

The easiest solution here is probably just to simply clone Vue repo and run $ yarn link vue in both the Vue app and the package.

0
votes

I recommend to define that code inside composable function like :

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}
}

then use it like :


<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>

EXAMPLE