Reputation: 71
I'm migrate Vue 2 to Vue 3. I'm using ag-grid and using buttons in every each row and these button using methods from parent component. In Vue 2 The syntax was simple: this.$parent.$parent (I'm usind twice $parent because of Ag-Grid) But now I'm facing with the Vue 3 and I want to getting the same component to work and doesn't have any idea how to write it.
I'm glad for helping
This is the code where I'm actually doing this:
<template>
<div class="main">
<i class="fa fa-info icons" @click="infoButton"></i>
<i class="fa fa-file icons" @click="filesHistoryButton"></i>
<i class="fa fa-edit icons" @click="editReminderButton"></i>
</div>
</template>
<script>
import defineComponent from "vue";
import { getCurrentInstance } from "vue";
export default defineComponent({
name: "Actions",
setup(){
const instace = getCurrentInstance();
console.log(instace.parent.parent)
},
data() {
return {};
},
computed: {},
beforeMount() {},
mounted() {},
methods: {
infoButton() {
this.$parent.$parent.GetNotificationHistory(this.params.data.id);
},
filesHistoryButton() {
this.$parent.$parent.GetFilesLists(this.params.data.id);
},
editReminderButton() {
this.$parent.$parent.EditReminder(this.params.data.id);
}
}
});
</script>
Upvotes: 4
Views: 6027
Reputation: 6886
For vue3 with <script setup>
, where you can't do this
,
and also can't use the option api (i.e. via defineComponent
) you can use getCurrentInstance().parent
:
<script>
defineComponent({
...,
setup() {
const myRef = this.$parent.$refs.myRef;
},
...,
});
</script>
This can be replaced by the following code:
<script>
const self = getCurrentInstance();
const myRef = self.parent.parent.parent.refs.myRef;
</script>
It seems in my code I needed two more .parent
then before - not sure if that's generally the case, but give it a try to add more or less of those.
Upvotes: 0
Reputation: 5181
The $parent
property should work with Vue 3 ether.
Be sure you don't use the expose declaration in your parent components, that limits the accessibility of your methods.
Like Estus Flask already said, this is not recommended practice, since it creates tight coupling between your components.
It would be much better to use custom events to interact with parent components.
See the Vue Docs about Component Events
Like this:
export default defineComponent({
name: "Actions",
emits: ['infoButton','filesHistoryButton','editReminderButton'], // <--- define events
setup(){
const instace = getCurrentInstance();
console.log(instace.parent.parent)
},
data() {
return {};
},
computed: {},
beforeMount() {},
mounted() {},
methods: {
infoButton() {
this.$parent.$parent.GetNotificationHistory(this.params.data.id);
this.$emit('infoButton', this.params.data.id);
},
filesHistoryButton() {
this.$parent.$parent.GetFilesLists(this.params.data.id);
this.$emit('filesHistoryButton', this.params.data.id);
},
editReminderButton() {
this.$parent.$parent.EditReminder(this.params.data.id);
this.$emit('editReminderButton', this.params.data.id);
}
}
});
And in the parent component accordingly:
@info-button="GetNotificationHistory"
Upvotes: 2