Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(reactivity): public contract for ref, reactive (fix vuejs/rfcs#129) #834

Closed
wants to merge 1 commit into from

Conversation

jods4
Copy link
Contributor

@jods4 jods4 commented Mar 14, 2020

This PR adds two new public functions: markRef and markReactive.
They are meant for advanced users or library authors and are only exported by @vue/reactivity, not vue itself.

The use-case here is to allow libraries to provide alternative, specialized implementations of the ref (observable value) and reactive (observable object) concepts.

Example use cases

One could want to create a ref that debounces its notifications:

function debouncedRef<T>(delay: number, value?: T) {
  let timeout = 0
  return markRef({
    get value() {
      track(this, TrackOpTypes.GET, 'value')
      return value
    },
    set value(v: T) {
      value = v
      clearTimeout(timeout)
      timeout = setTimeout(() => trigger(this, TriggerOpTypes.SET, 'value'), delay)
    }
  })
}

On the reactive side, one could want to create:

  • an implementation based on getter/setters rather than proxies (e.g. to work with classes using private fields);
  • an optimized reactive array that doesn't watch changes individually but as a whole;
  • "fake" reactive objects that do limited functionality, e.g. hideRefs({ a: ref(4) }) that only automatically unwrap refs.

Alternatives

It is possible to mark alternative implementations with markNonReactive but it doesn't integrate as well with Vue and some scenarios are broken.

For example, you can't make a Ref<T> in Typescript because the interface uses a private symbol to prevent that. This can only be worked around with <any> casts.

On the reactive side, some operations use toRaw (notably the template ref feature, e.g. <Component ref='x'>) and this is not exposed publicly so there is no way to tap into it.

RFC

Closes vuejs/rfcs#129

Adds markRef and markReactive so that users can provide alternate implementation of the ref and reactive concepts that work well with built-in ones.

closes vuejs/rfcs#129
@jods4
Copy link
Contributor Author

jods4 commented Mar 14, 2020

One test is failing in CI but it's not related to my changes, it's the markdown spec in examples.

@yyx990803
Copy link
Member

Closing per discussion in vuejs/rfcs#157

@yyx990803 yyx990803 closed this Apr 15, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Open Reactive API a little more
2 participants