Im creating a custom directive as follows in main.ts .
let handleOutsideClick: any;
app.directive("closable", {
mounted: (el, binding, vnode) => {
handleOutsideClick = (e: any) => {
e.stopPropagation();
const payload = binding.value;
console.log(`instance: ${Object.getOwnPropertyNames(binding.instance)}`);
};
document.addEventListener("click", handleOutsideClick);
},
unmounted: (el) => {
document.removeEventListener("click", handleOutsideClick);
},
});
Inside the event handler i want to make a call to a function on the component that triggered this directive.
With Vue 2 you could do it with vnode.context'myfunction' but this does not seem to work with binding.instance.
How can i call the function using the binding instance?
CodePudding user response:
Passing the function to be called as the binding's value and then calling it seems to work:
if (typeof binding.value === 'function') {
binding.value()
}
Working example:
const { createApp } = Vue;
const app = createApp({
setup() {
return { test: () => console.log('here') }
}
})
app.component('demo', {
template: `<div>test</div>`
})
let handleOutsideClick;
app.directive("closable", {
mounted: (el, binding, vnode) => {
handleOutsideClick = (e) => {
e.stopPropagation();
const payload = binding.value;
console.log(`instance: ${Object.getOwnPropertyNames(binding.instance)}`);
if (typeof binding.value === 'function') {
binding.value()
}
};
document.addEventListener("click", handleOutsideClick);
},
beforeUnmount: (el) => {
document.removeEventListener("click", handleOutsideClick);
},
});
app.mount('#app')
<script src="https://unpkg.com/[email protected]/dist/vue.global.prod.js"></script>
<div id="app">
<demo v-closable="test"></demo>
</div>
Notes:
- vue internal method names change based on environment. For example, if you remove
.prod
from the vue link in the example above, you'll get more data out ofObject.getOwnPropertyNames(binding.instance)
.
If your app's business logic relies on vue internals method naming:
a) you're doing it wrong™;
b) it won't work in production - if the above is not helpful, please provide more details on your specific use-case via a runnable minimal, reproducible example.
If you need a multi-file node-like online editor, note codesandbox.io allows importing local projects using their CLI utility.