Replies: 7 comments
-
|
This should be relevant for you: vuejs/core#1682 (comment) You didn't explain what use case makes you need a Ref inside the directive |
Beta Was this translation helpful? Give feedback.
-
|
@posva I was trying to create a |
Beta Was this translation helpful? Give feedback.
-
|
Maybe we can make |
Beta Was this translation helpful? Give feedback.
-
|
@yyx990803 makeExplicit? |
Beta Was this translation helpful? Give feedback.
-
|
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. |
Beta Was this translation helpful? Give feedback.
-
|
I have a similar use case to @Bond-Addict . I maintain a web component based component system and was trying to make a package for using something like I came up with the following, but it would be significantly less annoying if I didn't need to have users make a second function so I can get access to the raw ref. export default function (options = {}) {
if (!options) { options = {} }
if (!options.events) {
options.events = ["input", "change"]
}
if (!options.eventHandler) {
options.eventHandler = function (el, binding, vnode) {
return (event) => {
const model = binding.value
model.value = event.target.value
}
};
}
const { events, eventHandler } = options
return {
name: 'vue-wa-model',
install: (app, options) => {
const wm = new WeakMap();
app.directive("wa-model", {
beforeMount(el, binding, vnode) {
const inputHandler = eventHandler(el, binding, vnode)
wm.set(el, inputHandler);
const modelValue = binding.value.value
el.value = modelValue ?? null;
el.defaultValue = modelValue ?? null;
events.forEach((eventName) => {
el.addEventListener(eventName, inputHandler);
});
},
updated(el, binding) {
el.value = binding.value.value ?? null;
},
unmounted(el, _binding) {
const inputHandler = wm.get(el);
events.forEach((eventName) => {
el.removeEventListener(eventName, inputHandler);
});
wm.delete(el);
},
});
},
}
};And then here's the "hack" to pass the ref: <script setup>
const model = defineModel({ default: "value" })
// We need to prevent unwrapping of refs when passing to `v-wa-model`
const waModel = () => model
function update() {
model.value += "a"
}
</script>
<template>
<div class="outline wa-stack">
<h2>Options Test</h2>
<wa-input v-wa-model="waModel()"></wa-input>
<wa-input v-wa-model="waModel()" readonly></wa-input>
<div>Value: {{ model }}</div>
<button @click="update">Add "a"</button>
</div>
</template>I may just be holding it wrong, and this may be unrelated, but it would be really nice to pass a directive as a ref rather than always unwrapping it. |
Beta Was this translation helpful? Give feedback.
-
|
It is also my impression that template ref auto-unwrapping should be at least optional. I partly wrote about this in other discussion, but I'll outline the overall rationale here. First, my argument against auto-unwrapping is best summarized in the following statement:
I think the fundamental problem others encountered is that they tried to use the (I'd say, recommended and standard) Composition API pattern in SFC templates, namely, passing ref objects around just like with composables, but failed because of auto-unwrapping. Handling refs in SFC templates tends to be rather different than in other places. Then, two benefits of not auto-unwrapping refs are:
The reasons why the Reactivity Transform was dropped seem to partly support these benefits:
Currently, a compiled SFC's In addition, to further preserve compatibility refs could implement a const num = ref(1)
console.log(num + 1) // 2
const str = ref('foo')
console.log(`${str} bar`) // foo bar
|
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
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
Beta Was this translation helpful? Give feedback.
All reactions