Subscribe on changes!

vue3 computed not triggerd

avatar
Jul 20th 2023

Vue version

3.3.4

Link to minimal reproduction

..

Steps to reproduce

the 'params' is a ref

computed(() => {
       const originalArgs = toRaw(unref(params))
      const storeKey = JSON.stringify(originalArgs)
       return storeKey
})

What is expected?

computed be called

What is actually happening?

computed not be called

System Info

No response

Any additional comments?

No response

avatar
Jul 20th 2023

Please provide a runnable minimal reproduction.

avatar
Jul 20th 2023
Vue.createApp({
    setup() {
      function test(){
        params.value.x++;
      }

      const params = Vue.ref({ x: 1 })

      const label = Vue.computed(() => {
        const originalArgs =Vue.toRaw(Vue.unref(params))
        const storeKey = JSON.stringify(originalArgs)
        return storeKey 
      })

      return {
        label,
        test
      }
    },
    template: `  {{ label }}
    <button @click='test' >button</button>`
  })

if u click button . the label not chaneg . Is this your question ? @mnm1001

The reason why the label cannot be changed is u use the toRaw

when the computed invoke . u use toRaw to get value .

check the source code in L102-L105. it only return the target . not track(target, TrackOpTypes.GET, key) .

https://github.com/vuejs/core/blob/a3dddd62059f4a7a762046c1e7f01485b96e737d/packages/reactivity/src/baseHandlers.ts#L94C1-L156

maybe that's why

avatar
Jul 21st 2023

yes, it is my question

i know maybe if i called 'params.value.a' in computed like this

Vue.computed(() => {
        params.value.a
        const originalArgs =Vue.toRaw(Vue.unref(params))
        const storeKey = JSON.stringify(originalArgs)
        return storeKey 
      })

when 'params.value.a' be set new value, the computed will be called, but in my scenarios, I wanted to listen all deep changes for "params" in computed, may be the changed value is 'params.value.a', or 'params.value.b', or 'params.value.b.c.d',

That means, if the result of 'JSON.stringify(Vue.toRaw(Vue.unref(params)))' be changed, I expect the computed will be called.

Is there any solution for this scenarios?

avatar
Jul 21st 2023

That is works! Is this because JSON.stringify called all the "params" propety by recursion?

avatar
Jul 21st 2023

@mnm1001 this is because Vue does not track a raw value.