Daniel Nýdrle
Daniel Nýdrle

Reputation: 203

Vue.js methods shorthand

I would like to know whether it's possible to simplify this problem?

I have a bunch of button components named Btn like this:

<Btn content="7" @click="addSymbol(content)" />
<Btn content="8" @click="addSymbol(content)" />
<Btn content="9" @click="addSymbol(content)" />
<Btn content="/" @click="addSymbol(content)" />

I need to trigger the addSymbol method with the according content attribute and possibly, if I could simplify it so that I do not have to declare it on every single component?

Upvotes: 4

Views: 595

Answers (2)

maxshuty
maxshuty

Reputation: 10662

This answer assumes you can't just do a v-for on the <Btn> components for some reason. If so then wrap them in a div like this and we can use event bubbling:

<div @click="addSymbol">
  <Btn content="7" />
  <Btn content="8" />
  <Btn content="9" />
  <Btn content="/" />
</div>

Then in addSymbol you would take in the element like this:

addSymbol(el) {
 const content = el.currentTarget.getAttribute('content');
 // Do stuff
}

Upvotes: 2

Majed Badawi
Majed Badawi

Reputation: 28414

You can group the contents in an array and use v-for to create the components. To get the content of each, you can emit the prop as follows:

const btn = Vue.component('btn', {
  template: '#btn',
  props: ['content'],
  methods: {
    clicked() {
      this.$emit('click', this.content);
    }
  }
});

new Vue({
  el:"#app",
  components: { btn },
  data: () => ({ contents: ['7','8','9','/'] }),
  methods: {
    addSymbol(content) { 
      console.log(content);
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<template id="btn">
  <button @click="clicked">CLICK {{content}}</button>
</template>

<div id="app">
  <btn 
    v-for="(content, index) in contents" 
    :key="index"
    :content="content"
    @click="addSymbol" 
  />
</div>

Upvotes: 3

Related Questions