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.

$refs should be reactive to be able to use them in computed properties

See original GitHub issue

Now that refs are no longer reactive, we need to emit events and payloads from child components. This is fine and works well, but it becomes hard to maintain in the following scenario:

When you create a custom form input component, that basically wraps an input into it’s own re-usable component, we can no longer access the input’s value (and other props) reactively in e.g. a computed prop in the parent.

Take the following use-case:

<my-input ref="email"></my-input>
<my-input ref="password"></my-input>
<p>This is {{ isValid ? 'valid' : 'invalid' }}</p>

Previously we could create a computed prop like this:

isValid() {
  return this.$refs.email.isValid && this.$refs.password.isValid
}

Since refs don’t work reactively anymore, we now need to use $emit to inform the parent of changes. However, these emits are handled by methods, so we need a separate handler per input to deal with the events.

Something like:

<my-input @valid="handleValidEmail"></my-input>
<my-input @valid="handleValidPassword"></my-input>

handleValidEmail(value) {
  this.email = value
  this.emailIsValid = true
},

handleValidPassword(value) {
  this.password = value
  this.passwordIsValid = false
}

You could refactor this a bit, but it’s not a nice way of dealing with this and I’m assuming using forms is quite a common occurence for a lot of devs.

Can we think about a better solution to something like this?

Issue Analytics

  • State:open
  • Created 7 years ago
  • Reactions:116
  • Comments:52 (13 by maintainers)

github_iconTop GitHub Comments

47reactions
posvacommented, Jul 25, 2019

Although I don’t totally approve having reactive $refs as it can show a bad design choice in the model structure, I think it has its valid use cases so I created a small plugin to make $refs reactive: https://github.com/posva/vue-reactive-refs. It probably have caveats, so if you found any, please open an issue on the repo 🙂

15reactions
TheDutchCodercommented, Oct 4, 2016

Just to add some context, this is what I could do previously:

computed: {
  isReady() {
    return this.$refs.email.isValid && this.$refs.password.isValid
  }
}

But now I need to add additional state and a handler to deal with this:

data() {
  return {
    email: { value: '', isValid: false },
    password: { value: '', isValid: false }
  }
}

// Some method that dynamically handles input changes

// Computed prop
computed: {
  isReady() {
    return this.email.isValid && this.password.isValid
  }
}

Mainly the extra (not very useful) state and the handler are a bit of a pain, would be great if there could be some alternative to what used to be $refs that remain reactive. Not sure what the implications would be and why it was deprecated, I’m just trying to illustrate a use case when the old $refs were very useful.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Using $refs in a computed property - vue.js - Stack Overflow
$refs are only populated after the component has been rendered, and they are not reactive. It is only meant as an escape hatch...
Read more >
Choosing Between Ref and Reactive with Vue 3's ... - Netlify
An opinionated perspective on whether you should use ref or reactive in Vue 3's Composition API.
Read more >
This.$ref.el in computed property not reactive - Vue Forum
yes, refs are not reactive, so computed props are not a solution. you should not define state like that in the DOM. define...
Read more >
[Solved]-Using $refs in a computed property-Vue.js
$refs are only populated after the component has been rendered, and they are not reactive. It is only meant as an escape hatch...
Read more >
Must-Know Ref vs Reactive Differences In Vue 3 Composition ...
One of the ways we can create a property without losing its reactivity is by using ref(). The ref() object takes an inner...
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