missing instance information for directives in beforeMount hook when using setup syntax
Vue version
3.2.39
Link to minimal reproduction
https://stackblitz.com/edit/vitejs-vite-zmkeex?file=src/main.js
Steps to reproduce
- create a directive in
main.js
- create a component with the following properties:
- use the setup syntax
- create a function (empty script tag doesn't cause problems)
- in the template call the directive
What is expected?
in the beforeMount function, the options should have an instance property which has the information of the component which calls the directive.
What is actually happening?
the instance property contains an empty Proxy object
System Info
No response
Any additional comments?
In the stackblitz example I created a ComponentA.vue (setup syntax) and a ComponentB.vue to see how the instance property differs when the beforeMounted hook is called in both cases. The result is console logged.
You need to use defineExpose()
(which you do) to define properties that are available as properties on the instance object. Those will be exposed through the proxy you see logged to the console. you can verify that by loggingoptions.instance.myFunc
.
You need to use
defineExpose()
(which you do) to define properties that are available as properties on the instance object. Those will be exposed through the proxy you see logged to the console. you can verify that by loggingoptions.instance.myFunc
.
thanks for the tipp. That way quite a nasty bug on my side to hunt down. defineExpose()
did the trick indeed 👍 .
script setup instances are intentionally closed by default. no instance state is exposed to the outside unless it's explicitly mean to be.
This is a learning we had: When any property you use in your component can implicitly become part of its API consumed by other parts of the app through template refs or custom directives, you can easily break things by doing something as simple as refactoring a function in your component, or renaming a piece of state.
So when we designed script setup, we made it part of the "spec" that we make them "closed" by default and leave it to developers to explicitly define the APIs they want to expose with defineExpose()
.
The expose
feature is available on normal components as well, but for reasons it backwards compat, normal components are open by default until the dev explicictly exoses something