Reputation: 1146
I am trying to pass current component's ref to a child component like this:
<template>
<div class="screen" ref="screen">
<child-component :screenRef="screenRef">
</child-component>
</div>
</template>
<script>
const Parent = {
name: 'parent',
data: {
screenRef: {}
},
mounted() {
this.screenRef = this.$refs['screen']
}
}
</script>
Since Vue.js types don't support HTMLDivElement
, I am getting an error in child component when I define screenRef
as a prop.
const ChildComponent = {
name: 'child',
props: {
screen: {
type: HTMLDivElement,
default: {}
}
}
}
Could someone please tell the correct way to do this?
Upvotes: 31
Views: 59158
Reputation: 97
This is a common issue when e.g. implementing infinite scroll, where you need a parent container's ref to set up an IntersectionObserver
inside a child component.
This should also work: pass a getScreenRef
function that returns the ref and invoke it inside the child's mounted
method:
<template>
<div class="screen" ref="screen">
<child-component :getScreenRef="() => $refs['screen']">
</child-component>
</div>
</template>
<script>
const Parent = {
name: 'parent',
}
</script>
const ChildComponent = {
name: 'child',
props: {
getScreenRef: {
type: Function,
default: () => ({})
}
},
mounted() {
// by the time the mounted method is called, screen ref will be available
const screenRef = this.getScreenRef();
...
}
}
Upvotes: 3
Reputation: 7800
You do all the things correct. Just do not declare the required type
for the screen
prop in the child component. The following props: {screen: {default: {}}}
will do the trick.
As side notes:
The mounted
hook is the correct place to assign the $refs
elements to $data
items as the former is not defined at created
hook.
Vue has type: Object
that still would work well for your screen
prop type validation if you want to apply the props type validation.
If you by chance would want to assign the default
object value other than the empty {}
you have to assign it via function (unlike non-object data types):
default: function () {
return {a: 1, b: 2}
}
Upvotes: 5
Reputation: 719
You can change default to null too and remove type. In my case I had to pass ref from sibling.
const ChildComponent = {
name: 'child',
props: {
screen: {
default: null
}
}
}
Upvotes: 0
Reputation: 166
Just try to access parent from child component via:
this.$parent
or
this.$el.parent
or use inheritAttrs option in child component for nontransparent pass of attributes from parent to child:
const ChildComponent = {
inheritAttrs: true,
name: 'child',
props: {
screen: {
type: HTMLDivElement,
default: {}
}
}
}
Upvotes: 13
Reputation: 919
If you need data from different component just pass it with props.
Or if you need this data in multiple components try Vuex:
Upvotes: 2