0

In my vue app i am calling a function on click event, which is located in a component. Here is the component code:

Vue.component( 'new-board', {
  template: `
    <div>
      <br/>
      <div class="panel panel-primary">
        <div class="panel-heading">
          Create New Board
        </div>
        <div class="panel-body">
          <input class="form-control" placeholder="Board Name"/>
          <button 
            style="margin-top: 5px;" 
            @click.stop="addBoard"
            class="btn btn-success btn-xs btn-block"
          >
            Add Board
          </button>
        </div>
      </div>
    </div>
  `
} )

Here is the vue app instance:

var boardItem = new Vue( {
  el: "#board-item",
  data: {
    boards: [
      { name: 'learning vue 2' }
    ],
    newBoard: [],
    viewNewBoard: true
  },
  methods: {
    displayNewBoard: function() {
      event.preventDefault()
      if( this.viewNewBoard == false ) {
        this.viewNewBoard = true
      } else {
        this.viewNewBoard = false
      }
    },
    addBoard: function() {
      console.log( 'add board' )
    }
  }
} )

Now, when i click on the Add Board button from the above component, it is showing this error:

Uncaught ReferenceError: addBoard is not defined at click (eval at Xr (vue.min.js:7), :2:455) at HTMLButtonElement.invoker (vue.min.js:6)

It seems that the button from the component can't find the addBoard method, which is written in the same file! What i am missing here?

1
  • Components cannot directly call methods defined on the parent Vue. You need to define addBoard on the component. Commented Feb 9, 2017 at 19:41

2 Answers 2

1

Try:

Vue.component( 'new-board', {
  template: `
    <div>
      <br/>
      <div class="panel panel-primary">
        <div class="panel-heading">
          Create New Board
        </div>
        <div class="panel-body">
          <input class="form-control" placeholder="Board Name"/>
          <button 
            style="margin-top: 5px;" 
            @click.stop="addBoard"
            class="btn btn-success btn-xs btn-block"
          >
            Add Board
          </button>
        </div>
      </div>
    </div>
  `,
  methods: {
    addBoard: function(){ console.log('add board');}
  }
} )
Sign up to request clarification or add additional context in comments.

Comments

0

A few changes here, if you want to share events with components that are not related you must use a new vue instance to fire those events and listen. So based on your code this should help.

window.Event = new Vue();

Vue.component( 'new-board', {
  template: `
    <div>
      <br/>
      <div class="panel panel-primary">
        <div class="panel-heading">
          Create New Board
        </div>
        <div class="panel-body">
          <input class="form-control" placeholder="Board Name"/>
          <button 
            style="margin-top: 5px;" 
            @click.stop="addBoard" // keep this as the name of the local method
            class="btn btn-success btn-xs btn-block">
            Add Board
          </button>
        </div>
      </div>
    </div>
  `,
   methods:{
        addBoard(){
             // fire the event, also you can add any params
             Event.$emit('callAddBoard',data)
        }
   }
} )

And the main instance should listen to that event

var boardItem = new Vue( {
  el: "#board-item",
  data: {
    boards: [
      { name: 'learning vue 2' }
    ],
    newBoard: [],
    viewNewBoard: true
  },
  methods: {
    displayNewBoard: function() {
      event.preventDefault()
      if( this.viewNewBoard == false ) {
        this.viewNewBoard = true
      } else {
        this.viewNewBoard = false
      }
    },
    addBoard: function() {
      console.log( 'add board' )
    }
  },

   created(){
         // here you listen and excute the remote event from component, and apply a local method.
         Event.$on('callAddBoard', this.addBoard)
   }
} )

As far as I tried this works , and you can send events to any component without the need of passing through the main instance.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.