vuejs / rfcs

RFCs for substantial changes / feature additions to Vue core
4.86k stars 548 forks source link

API to prevent refs from being unwrapped #533

Closed jfet97 closed 1 year ago

jfet97 commented 4 years ago

What problem does this feature solve?

Not unwrappable refs will be able to passed as values to custom directives without loosing their essence

I was building a custom directive that needs a ref as a value, to then perform some changes to that ref in response to some events. I was just experimenting, nothing too serious, but unfortunately I later realized that the automatic refs unwrapping when a ref is used inside a template will always prevents the creation of this kind of directives.

We are forced to use reactive to create a sort of notUnwrappableRef and for consistency we end up creating a reactive object with only one reactive property: value.

What does the proposed API look like?

Something like the following, but standardized for every user

import { reactive } from "vue"

export function notUnwrappableRef(value) {
    return reactive({ value })
}
posva commented 4 years ago

This should be relevant for you: https://github.com/vuejs/vue-next/pull/1682#issuecomment-663421117 it explains some upcoming changes and why the unwrapping exists

You didn't explain what use case makes you need a Ref inside the directive

jfet97 commented 4 years ago

@posva Passing a ref to a directive let the directive's hooks change the ref value.

I was trying to create a stream like directive (https://github.com/vuejs/vue-rx/blob/master/src/directives/stream.js) using refs instead of observables. I'm not saying that this example is a good way to do things, but it shows that the union of refs and directives could allow interesting stuff.

yyx990803 commented 4 years ago

Maybe we can make markRaw also prevent refs from being unwrapped?

jfet97 commented 4 years ago

@yyx990803 It could be an idea, even if, sincerely, I do not associate the term raw with this characteristic. On the other hand, I understand that "something that is not automatically unwrapped by Vue" is not easy to put inside a word or two.

makeExplicit?

Bond-Addict commented 1 year ago

I would like to add support for this feature. I'm utilizing a library that expects a ref. The way you normally use it is on the actual component itself, but I would like to have the ref come from a parent and then use the function in the child. I cannot accomplish this because the ref is automatically unwrapped which causes value to be undefined which is the property that the library acts on. Below is an example of how the library expects the code to be:

<template>
    <va-form ref="form"></va-form>
</template>
<script setup lang="ts">
const form = ref()

const { validate } = useForm(form)

validate()
</script>