Subscribe on changes!

changes to nonreactive variables containing primitive values are reflected in prod, but not in dev.

avatar
Apr 1st 2022

Version

3.2.31

Reproduction link

sfc.vuejs.org/

Steps to reproduce

const foo = shallowRef({foo:1})

The element node should not be updated when the shallowRef changes. However, when other responsive data changes, the element node(bound to shallowRef) is also updated

What is expected?

not updated

What is actually happening?

element node updated

avatar
Apr 1st 2022
// Result of compilation
_createElementVNode("div", _hoisted_1, _toDisplayString(_unref(foo).fooProp), 1 /* TEXT */),
    _createElementVNode("div", _hoisted_2, _toDisplayString(bar.value), 1 /* TEXT */),
// I guess both of that should be tagged STATIC or hoisted
avatar
Apr 1st 2022

I'm not sure what what you mean with "only happens in SFC playground".

What you see there is normal. when one reactive dependency of the template changes, the whole component is re-rendered, with all the latest data.

So I'm not sure what behavior you expect.

avatar
Apr 1st 2022

I'm not sure what what you mean with "only happens in SFC playground".

https://user-images.githubusercontent.com/30561277/161329929-05c80ef9-c299-422f-82bd-096dbf14874d.mov Same code in my project(vue version 3.2.31), #nonReactive wasn't updated. This's different from what I've seen in SFC playground.

What you see there is normal. when one reactive dependency of the template changes, the whole component is re-> rendered, with all the latest data.

When I tested it in my project, I considered that all non-responsive data would not update the DOM ( like nonReactive in video )

avatar
Apr 1st 2022

Thanks for the video, but that doesn't tell me much without understanding how exactly to replicate it.

avatar
Apr 1st 2022

https://github.com/xiexuan-star/issue-demo You can clone it. It is already late at night in my country, so I may not be able to reply to you in time

avatar
Apr 2nd 2022

you seem to have forgotten to push some changes to that repo? it only has the default project files, no changes related to what you show in the play ground.

avatar
Apr 2nd 2022

I just pushed my code. I forgot to check. I'm sorry.

avatar
Apr 2nd 2022

No I see what you mean. This is in fact a side-effect of the way script setup is compiled for dev. it essentially looks like this:

import { ref,shallowRef, defineComponent } from 'vue'

export default defineComponent({
  setup() {
    const foo = shallowRef({fooProp:1})
    const bar = ref(1);
    let nonReactive = 1
    function onClick(){
      foo.value.fooProp++;
      bar.value++;
      nonReactive++;
    }

    return {
      foo,
      bar,
      nonReactive // this will now forever be 1, as it reassigned a primitive value to an object property
    }
  }
})

Whereas in production/playground, it will look more like this: