vuejs / core

🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
https://vuejs.org/
MIT License
47.54k stars 8.31k forks source link

Add `name` field to directives to allow stubbing directives by name #6887

Open xanf opened 2 years ago

xanf commented 2 years ago

What problem does this feature solve?

Hi! @vue/test-utils maintainer here!

With <script setup> being a recommend way to use Vue3, there is a regression in testing experience compared to Vue2 + @vue/test-utils v1 in stubbing directives.

Previously, we were able to stub directives by name for the components (both SFC and using render functions).

However, in <script setup> directive name is just a local variable name, not being exposed to vnode or component type by any means.

The easiest solution might be just to add name field to directives in the same way we have name for components (actually it is there when directive is declared as a function because function have names :smile:). This will allow us to stub directives in the same way as components - by using global name

What does the proposed API look like?

Simply add name?: string to ObjectDirective interface and update relevant docs:

export declare interface ObjectDirective<T = any, V = any> {
+   name?: string  
    created?: DirectiveHook<T, null, V>;
    beforeMount?: DirectiveHook<T, null, V>;
    mounted?: DirectiveHook<T, null, V>;
    beforeUpdate?: DirectiveHook<T, VNode<any, T>, V>;
    updated?: DirectiveHook<T, VNode<any, T>, V>;
    beforeUnmount?: DirectiveHook<T, null, V>;
    unmounted?: DirectiveHook<T, null, V>;
    getSSRProps?: SSRDirectiveHook;
    deep?: boolean;
}
filamin commented 2 months ago

There is a similar problem. I need to migrate component from Vue2 to Vue3 and there is a logic of removing directive by name in the component. The field name in the current DirectiveBinding would help.