[Vuejs]-Passing parent vm as a prop to a component

0👍

IF your Menu is always the child of the component, then you don’t have to pass your parent. It is already held in a Vue variable called this.$parent.

I made a little sandbox to give you an example.

The parent has a function, for example:

/// PARENT

export default {
  name: "App",
  components: {
    HelloWorld,
  },
  methods: {
    iExist(add) {
      console.log("I am in parent" + add);
    },
  },
};

Then you can call it from child with this.$parent.iExist('something').

Since this.$parent is not defined when the template is being evaluated, we have to make a method in the child as well, to call(super) the corresponding function on it’s parent.

/// CHILD
<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <button @click="iExist(', but was called from child')">Click Me</button>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  props: {
    msg: String,
  },
  methods: {
    iExist(add) {
      this.$parent.iExist(add);
    },
  },
};
</script>

0👍

The question: Is there something intrinsically bad in this approach?

(I imagine this could be problematic if the app architecture could change, but it’s hard to imagine that I would for some reason need a menu without an underlying document.)

Yes, this is bad design. Parents can be aware of children, children shouldn’t be aware of parents. A child could be tested in isolation, or be nested inside wrapper component that doesn’t have this method.

As another answer suggests, a way to access a parent is to use $parent property. This part was borrowed in Vue from AngularJS 1.x, accessing it was considered a bad practice even then.

This is generally achieved by providing a callback from a parent that does exactly a desired thing, without allowing to access the whole instance and break the encapsulation. It’s unnecessary to explicitly define callback function in Vue because this is naturally provided by Vue template syntax:

In a parent:

<child @save="save()">

In a child:

<button @click="$emit('save')">

In case of deeply nested components the event can be passed through them to a parent.

Leave a comment