I am facing an issue with accessing a child element's method from the parent element using ref='menu'. When I try to call $refs.menu.show in a button element within the Vue app, it works fine. However, when I try to do the same in a photo element, it doesn't work. All components are registered in the parent Vue app.
//ERROR
vue.js:634 [Vue warn]: Error in v-on handler: "TypeError: Cannot read property 'show' of undefined"
found in
---> <Photo>
<Root>
Here is my HTML code inside #app:
// For tests
<button @click.prevent='$refs.menu.show'></button>
<div class="center" :style="{ width : center_div_width+'px', height : window_height+'px'}">
<template v-for='(row, index1) in info'>
// Parent element
<photo v-for="(item, index2) in row" :item="item" :art_width='art_width'>
// Child element
<cmenu ref='menu'>
<li>Test</li>
<li>Test2</li>
</cmenu>
</photo>
</template>
</div>
// JS
Components that I am using. I am attempting to call a nested app method from the template of the 'photo' component:
Vue.component('photo', {
props: ['item', 'art_width'],
template: `<a class='art' href="" :style="offset(item.offsetX, item.offsetY)" @mouseover="hover = true" @mouseout="hover = false">
<img v-bind:src="/media/ + item.path" class="img" :width="art_width+'px'">
<a href="" class='art-owner' align="center" v-show='hover'>{{item.owner}}</a>
<a href="" class='art-menu' align="center" v-show='hover' @click.prevent='$refs.menu.show'>...</a>
<slot></slot>
</a>`,
data: function () {
return {
hover: false,
}
},
methods: {
offset (valueX, valueY) {
return `transform: translateX(${ valueX }) translateY(${ valueY })`
},
},
})
context_menu = Vue.component('cmenu', {
template: `<div class='context-menu'>
<ul>
<slot></slot>
</ul>
</div>`,
data: function () {
return {
ifshow: false,
style = null
}
},
mounted() {
window.addEventListener('click', (event) => {
if (Object.is($el, event.target) == true) {
this.ifshow = false;
}
});
},
methods: {
show: function(event) {
this.ifshow = true;
}
}
})