Subscribe on changes!

Reactivity Transform not working with provide/inject

avatar
Jun 12th 2022

Vue version

3.2

Link to minimal reproduction

https://sfc.vuejs.org/#__DEV__eyJBcHAudnVlIjoiPHNjcmlwdCBzZXR1cD5cbmltcG9ydCBDYW52YXMgZnJvbSBcIi4vQ2FudmFzLnZ1ZVwiXG5pbXBvcnQgQ2lyY2xlIGZyb20gXCIuL0NpcmNsZS52dWVcIlxuPC9zY3JpcHQ+XG5cbjx0ZW1wbGF0ZT5cbiAgPENhbnZhcz5cbiAgICA8Q2lyY2xlIC8+XG4gIDwvQ2FudmFzPlxuPC90ZW1wbGF0ZT4iLCJpbXBvcnQtbWFwLmpzb24iOiJ7XG4gIFwiaW1wb3J0c1wiOiB7XG4gICAgXCJ2dWVcIjogXCJodHRwczovL3NmYy52dWVqcy5vcmcvdnVlLnJ1bnRpbWUuZXNtLWJyb3dzZXIuanNcIixcbiAgICBcInZ1ZS9zZXJ2ZXItcmVuZGVyZXJcIjogXCJodHRwczovL3NmYy52dWVqcy5vcmcvc2VydmVyLXJlbmRlcmVyLmVzbS1icm93c2VyLmpzXCJcbiAgfSxcbn0iLCJDYW52YXMudnVlIjoiPHNjcmlwdCBzZXR1cD5cbmltcG9ydCB7IHJlZiwgY29tcHV0ZWQsIHdhdGNoRWZmZWN0LCBwcm92aWRlfSBmcm9tICd2dWUnXG5pbXBvcnQgQ2lyY2xlIGZyb20gJy4vQ2lyY2xlLnZ1ZSdcblxuY29uc3QgY2FudmFzID0gJHJlZigpXG5jb25zdCBjdHggPSAkY29tcHV0ZWQoKCkgPT4gY2FudmFzPy5nZXRDb250ZXh0KCcyZCcpKVxucHJvdmlkZSgnY2FudmFzJywgY2FudmFzKVxucHJvdmlkZSgnY3R4JywgY3R4KVxuXG5cbjwvc2NyaXB0PlxuXG48dGVtcGxhdGU+XG4gIDxjYW52YXMgcmVmPVwiY2FudmFzXCIgd2lkdGg9XCI0MDBcIiBoZWlnaHQ9XCI0MDBcIiBzdHlsZT1cImJvcmRlcjoxcHggc29saWQgIzAwMDAwMDtcIj5cbiAgICA8c2xvdCA+ZGVmYXVsdDwvc2xvdD5cbiAgPC9jYW52YXM+XG48L3RlbXBsYXRlPiIsIkNpcmNsZS52dWUiOiI8c2NyaXB0IHNldHVwPlxuaW1wb3J0IHtpbmplY3QsIHdhdGNoRWZmZWN0fSBmcm9tICd2dWUnXG4gIFxuY29uc3QgY2FudmFzID0gaW5qZWN0KCdjYW52YXMnKSAgXG5jb25zdCBjdHggPSBpbmplY3QoJ2N0eCcpICBcblxud2F0Y2hFZmZlY3QoKCkgPT4ge1xuICBpZiAoY3R4KSB7XG4gICAgY3R4LmJlZ2luUGF0aCgpO1xuICAgIGN0eC5hcmMoOTUsIDUwLCA0MCwgMCwgMiAqIE1hdGguUEkpO1xuICAgIGN0eC5zdHJva2UoKTtcbiAgfVxufSlcblxuXG48L3NjcmlwdD5cblxuXG5cbjx0ZW1wbGF0ZT48L3RlbXBsYXRlPiJ9

Steps to reproduce

Using provide/inject using Reactivity Transforms such as $ref and $computed doesn't work the same as without the transform (ref.value, computed.value,...etc)

What is expected?

Expected to be able to reference a provided/injected reference to a $ref or $computed property from parent component in child component.

What is actually happening?

The reference doesn't work. Although when tried the same example with ref and computed properties and using the .value in the child everything worked just fine.

System Info

No response

Any additional comments?

No response

avatar
Jun 12th 2022

Please read the docs carefully - https://vuejs.org/guide/extras/reactivity-transform.html#retaining-reactivity-across-function-boundaries

Your first issue is in Canvas.vue where you actually provide value of the ref/computed property instead of ref/computed object itself. That's why you have to use $$()

provide('canvas', $$(canvas))
provide('ctx', $$(ctx))

The second problem is with the way you use injected values in Circle.vue.

const ctx = inject('ctx')

watchEffect(() => {
  if (ctx) {

  }
})

Here, ctx is a ref object but you do not use .value explicitly. Once again you have to use $() to tell the compiler that you want to treat this variable as a ref.

const canvas = $(inject('canvas')) 
const ctx = $(inject('ctx'))

Fixed example

avatar
Jun 12th 2022

Yes , Thank You so much. I get it now. I had read that part in the docs. I just didn't think that this will apply to provide/inject as well.