question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Limited set of reactive props for a data nested object

See original GitHub issue

What problem does this feature solve?

Referencing a big object in the data of a component can lead to performance issues: indeed Vue automatically recursively observes all properties found in the object.

This is not ideal to reference big objects that are not just pure data or states, but especially in the context of a progressive migration of a legacy application to Vue (ie. adding new components on top of an existing architecture), one can have parts of existing big objects to observe for components to react seamlessly.

I had performance issues when referencing an object having itself references to Three JS stuffs (meshes…): interacting with the 3D scene was much slower after the instantiation of the Vue component, whereas I just needed some properties at the root of this object to become reactive.

Thus I suggest adding the possibility to specify a limited set of properties to observe for an object referenced in the data of a component.

A good practice in such case is certainly to isolate the needed properties inside a much smaller object without uncontrolled content, but in the context of a progressive migration, refactoring things cannot always be an option. Copying and/or partially freezing the object is not an option in my case as it needs to stay mutable for the existing application to keep working. In my case the interesting properties being of simple types (String, Number, boolean…) and being at the root of the big object, the entry point is the big object itself.

In my mind Vue is recommended for eg. over React for projects where you want a progressive migration towards a modern component-based framework, and in this context adding this feature would help.

(Previously discussed here: https://forum.vuejs.org/t/limited-set-of-reactive-props-for-a-data-nested-object/)

I could work on a PR, even if I don’t have a lot of time, but for the moment this is just a feature suggestion 😃

What does the proposed API look like?

// src/someLegacyModule.js
export const bigOject = {
  propA: ...,
  propB: ...,
  bar: {
    deeperProp: ...,
    // lots of stuffs we don't need in our Vue components
  }
  // lots of stuffs we don't need in our Vue components
}

Initially I thought of something like the following, but it could be considered as not totally consistent with the framework as an import is needed:

import bigObject from '@/src/someLegacyModule'
import { PartialObserver } from 'vue'

export default {
  template: `
    <div>
      {{ foo.propA }}
      <div v-if="foo.propB">{{ foo.bar.deeperProp }}</div>
    </div>
  `,
  data () {
    return {
      // only make needed properties reactive on bigOject (as it could be huge and very deep)
      foo: PartialObserver(bigObject, ['propA', 'propB', 'bar.deeperProp']),
    }
  }
}

Or maybe something like this, without additional import:

export default {
  data () {
    return {
      foo: {
        // only make needed properties reactive on bigOject (as it could be huge and very deep)
        __partialObserver: [bigObject, ['propA', 'propB', 'bar.deeperProp']])
      }
    }
  }
}

The name of the added special property where we can define the limited list of properties to make reactive could be different: '_observeOnly', '_watchOnly', '_reactiveProps' … ? Maybe adding a $ or _vue prefix (but I know this is more for Vue internals) ?

It could also be separate, as not adding an extra level of indirection may be easier to implement:

export default {
 data () {
   return {
     foo: bigObject,
     __settings: {
       foo: {
         watchOnly:  ['propA', 'propB', 'bar.deeperProp']
       }
     }
   }
 },
 // ... or instead of the above:
 // dataConfig: {
 //   foo: {
 //     watchOnly:  ['propA', 'propB', 'bar.deeperProp']
 //   }
 // },
}

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:6 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
posvacommented, Jul 14, 2019

Thanks for the proposal. To make things non reactive you can use Object.defineProperty or Object.freeze if you don’t want to modify the object anymore which is also a simple straight call to

Here is an example using Object.defineProperty and Object.freeze: https://jsfiddle.net/posva/fdruqp3v/

This will allow you to create your PartialObserver function or even a plugin to handle a nonReactive property. There is also https://github.com/rpkilby/vue-nonreactive which uses a slightly different solution

0reactions
colin-guyoncommented, Jul 14, 2019
Read more comments on GitHub >

github_iconTop Results From Across the Web

Limited set of reactive props for a data nested object - Get Help
Hi, I am progressively adding Vue stuffs and converting things in a legacy app. When creating components and defining its data, ...
Read more >
Understanding the New Reactivity System in Vue 3 - SitePoint
shallowReactive creates a reactive proxy which tracks only its own properties excluding nested objects. shallowReadonly creates a readonly ...
Read more >
Vue, how to handle reactivity with deeply nested objects
The Array in key2 is a prop where the inner keys are expected to mutate. I want to maintain reactivity when innerKey1 or...
Read more >
Vue.js - Set, Get & Delete Reactive Nested Object Properties
The setProp() function is used to set a deep property on an object and hook it into the Vue.js reactivity system. Example: to...
Read more >
Documentation - SolidJS · Reactive Javascript Library
import { mergeProps } from "solid-js"; function mergeProps(...sources: any): any;. A reactive object merge method. Useful for setting default props for ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found