Liran Hersh
Liran Hersh

Reputation: 71

Vue 3 - get access to parent

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

Answers (2)

luckydonald
luckydonald

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

Tolbxela
Tolbxela

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

Related Questions