Search code examples
javascriptvue.jscomponents

Ho to properly pass a method in a child component in Vue.js?


I have a child component called goback.vue which only function is to go back one step in the navigation history. The reason why I am asking this question is because I am trying to reuse this component often in many other components and I want to be able to edit the style and template later on just one place.

This is the code of the component goback.vue:

<template>
    <span @click="backOneStep">
       <svg type="submit" class="arrowleft" >
          <use href="../static/icons/iconsset.svg#arrowleft"></use>
       </svg>
    </span> 
</template>
<script>
export default {
    name: 'goback',
    data () {
        return {
        }
    },
    methods: {
        backOneStep(){
        window.history.go(-1)
        },
    } 
}     
<script>

Then on my several of my parent components I am importing the child component in the following manner:

<template>
  <div class="building">
    <div id="title">
      <goback></goback> // using the child component here
    </div>  
  </div>
</template>
<script>
import goback from './goback.vue';
export default {
  components: {
    goback
  },
  name: 'maincomponent',
  data () {
    return {  
      }
    }
  },
  methods: { 
     backOneStep(){ // do I need to repeat this here?
      window.history.go(-1) 
    },
  }
}
</script>

First, I am wondering if I need to repeat the method on all parent components or if I can just write it on my child component. Second, I am getting an error message:

[Vue warn]: Property or method "backOneStep" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.

found in

 <Goback> at src/components/goback.vue
   <Depts> at src/components/depts.vue
     <App> at src/App.vue
       <Root>

Note: I have carefully read the link but I am still stuck

Immediately following the previous error message I am also getting this error message:

[Vue warn]: Invalid handler for event "click": got undefined

found in

 <Goback> at src/components/goback.vue
   <Depts> at src/components/depts.vue
     <App> at src/App.vue
       <Root>

Would be able to tell me what I can do to avoid this? Is this related to props? I have tried declaring the "backOneStep" prop in the data of the goback.vue but I am not sure I have done it correctly. What am I missing here?


Solution

  • You can use a $emit event to tell the parent to "go back" on click in the child component:

    <template>
      <span @click="backOneStep">
        <svg type="submit" class="arrowleft" >
          <use href="../static/icons/iconsset.svg#arrowleft"></use>
        </svg>
      </span> 
    </template>
    <script>
      export default {
        name: 'goback',
        methods: {
          backOneStep() {
            this.$emit('back')
          }
        } 
      }     
    </script>
    

    And in the parent:

    <template>
      <div class="building">
        <div id="title">
          <goback @back="window.history.go(-1)"></goback>
        </div>  
      </div>
    </template>