Issue
I created a directive, and I need to make that directive call a function that exists inside the component that has the directive.
// Component with directive, this component has the method 'setDisabled()'
<v-button v-can:edit.disable="[something]" @click="add" />
// Directive created
const can = {
mounted: async (el, binding, vnode) => {
let hasAccess = validateAccess()
if (!hasAccess) {
// should call v-button setDisabled() in here
}
},
}
In VUE 2 that was achievable by using vnode.context, but in VUE 3 it seems like I can only access methods from the parent component with binding.instance.
So, is there a way to use el, binding or vnode, after the component is mounte to call a method? So far just saw the props in vnode, no methods or reactive data.
Solution
Hacked solution for Vue3
Constraints
- The Vue Doc clarifies
Official Docs: Script Setup Components using
<script setup>
are closed by default - i.e. the public instance of the component, which is retrieved via template refs or $parent chains, will not expose any of the bindings declared inside .Official Docs: Custom Directives In general, it is not recommended to use custom directives on components.
The
binding.instance
argument passed to the directive hook represents- The parent component having an element/component that uses the v-directive
- Not the component that defines the v-directive.
The
vnode
argument passed to the directive hook represents- The element that uses v-directive for
Native DOM Element
- The root element of component that uses v-directive for
Custom component with single root
- The first root element of component that uses v-directive for
Custom component with multiple roots
- The element that uses v-directive for
However
- You can access the custom component instance using vnode
- And you can access underlying method of the custom component from vnode using
- Expose
vnode.el.__vueParentComponent.exposed
- Provide
vnode.el.__vueParentComponent.provides
- Expose
Solution:
- Expose the component method using defineExpose
const setDisabled = () => { /* Your precious method */};
defineExpose({
setDisabled
});
- Access the exposed method using vnode
const vCan = {
mounted: async (el, binding, vnode)=> {
vnode.el.__vueParentComponent.exposed.setDisabled()
},
};
- Also ensure the directive definition object is defined using camelCase and has v prefix like
vCan
Answered By - Alpesh Patil Answer Checked By - Mary Flores (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.