I'm running into an issue with Vue 3 (alpha 4):
Inside the setup()
function I am trying to read the parent component. As per the documentation on https://vue-composition-api-rfc.netlify.com/api.html#setup it should expose the parent via the context
argument, either as a property of context.attrs or directly as parent (see the SetupContext
bit under 'typing'). I don't find the documentation to be very clear on whether parent
should be accessed directly from SetupContext
, or via SetupContext.attrs
, so I've tried both ways, but to no avail.
Here's my issue, I can access the SetupContext
and SetupContext.attrs
(which is a Proxy) just fine when logging them. SetupContext.attrs
exposes the usual proxy properties ([[Handler]]
, [[Target]]
and [[IsRevoked]]
) and when inspecting [[Target]]
it clearly shows the parent property.
When logging the parent though, it just prints out undefined:
export default {
setup(props, context) {
console.log(context);
// Output: {attrs: Proxy, slots: Proxy, emit: ƒ}
console.log(context.attrs);
// Output: Proxy {vnode: {…}, parent: {…}, appContext: {…}, type: {…}, root: {…}, …}
console.log(context.attrs.parent);
// Output: undefined
}
};
Spreading the context yields the same result:
export default {
setup(props, { attrs, parent }) {
console.log(attrs);
// Output: Proxy {vnode: {…}, parent: {…}, appContext: {…}, type: {…}, root: {…}, …}
console.log(attrs.parent);
// Output: undefined
console.log(parent);
// Output: undefined
}
};
I'm a bit new to proxies in JavaScript, but from what I've read on them, and from experimenting with proxies returned by reactive() for example. I should just be able to access the property like I normally would with an object. Any ideas on what I'm doing wrong?
I've created a codesandbox to reproduce the problem
The setup() hook serves as the entry point for Composition API usage in components in the following cases: Using Composition API without a build step; Integrating with Composition-API-based code in an Options API component.
How to access the props object inside <script setup> ? In the composition API, you need to explicitly define the props in <script setup> to be able to use the props object.
To call methods in a child component from the parent, we assign a ref to the component and get its methods from there. If we want to call a method in the parent component from the child, then we emit an event in the child component and listen to that event in the parent component.
You can use getCurrentInstance
. Vue documentation.
Its as easy as:
import { getCurrentInstance } from "vue";
export default {
setup(props) {
const instance = getCurrentInstance();
console.log("parent");
console.log(instance.parent);
}
}
Also, probably worth noting that Vue composition api plugin exposes parent in the same way, but it is referenced as instance.$parent
there.
I know this doesn't answer the question directly, but using provide/inject (https://v3.vuejs.org/guide/component-provide-inject.html) has helped me resolve this same issue where I wanted to get a data attribute from the parent node and to pass it to the rendered component, but could not access the parent anymore after upgrading from Vue2 to Vue3. Rather than trying to expose the parent, I passed a prop from its dataset down to the rendered component.
Upon creating the app, I did the following.
main.js
import { createApp } from "vue";
import MyComponent from './components/MyComponent.vue';
const section = document.getElementById('some-element'); // this element contains a data-attribute which I need to use within the app. In my case, I can't get the data from the component created/mounted function as the section with the data attribute is loaded onto the page multiple times with different attributes each time.
const app = createApp(MyComponent);
app.provide('dataset', section.dataset.id); // section.dataset.id contains some kind of id, let's say 'abc123' for the sake of this example
app.use(store); //not relevant for this answer
app.mount(section);
Then, inside the component, I could access the 'dataset' by doing the following.
MyComponent.vue
<template>
<div>Normal template stuff here</div>
</template>
<script>
export default {
name: 'MyComponent',
inject: ['dataset'], // the magic
created() {
console.log(this.dataset); // will log 'abc123'
}
}
</script>
This is very stripped down, but shows my case nicely i guess. In any case, if you're trying to do something similar and want to get data via parent data attribute, you could look into provide/inject.
Hope it helps anyone out there!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With