3

I'm starting with Vue and I'm having a little difficulty.

In the image below I have a table with some items:

table with items

Every time an item is chosen and the amount increased I need that in my addOptional method (optional) my variable gets the amount of that item concatenated with the value. Example if I choose hammer would look like this `

let variavel = opcional.Qtd + 'x' + opcional.Code

If I give console.log the result would be 2x1

But if I choose another option, example Serrote I should join the first choice in that same variable and separate with Pipe ( | ) Example would look like this.

2x1 | 1x2

How should I do this? Should I use array?

What I already have:

new Vue({
  el: '#app',
  data() {
    return {
      Opcionais: [
        { Code: 1, Nome: 'Martelo', Valor: 50.00, Qtd: 0 },
        { Code: 2, Nome: 'Serrote', Valor: 50.00, Qtd: 0 },
        { Code: 3, Nome: 'Prego', Valor: 60.00, Qtd: 0 }
      ]
    }
  },
  methods: {
    addOpcional(opcional) {
      // The variable below should receive the value of the quantity plus the code. If more than one option is chosen the variable must receive this new value and separate with pipe example Qty (2) x Code (2) | Qty (3) x Code (2)
      opcional.Qtd += 1

      let Code = [opcional.Qtd + 'x' + opcional.Code]
      },

    remove(opcional) {

    }
  }
})
<script src="https://unpkg.com/vue"></script>

<div id="app">
  <template>
    <div class="usuario-lista">
      <table>
        <thead>
          <tr>
            <th>#Code</th>
            <th>Nome</th>
            <th>Valor Unitário</th>
            <th>Valor Total</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="opcional in Opcionais" :key="opcional.Code">
            <td>
              <button @click="opcional.Qtd ? opcional.Qtd-- : false">-</button>
              <input type="text" :value="opcional.Qtd">
              <button @click="addOpcional(opcional)">+</button>
            </td>
            <td>{{ opcional.Nome }}</td>
            <td>{{ opcional.Valor }}</td>
            <td>{{ opcional.Valor * opcional.Qtd }}</td>
          </tr>
        </tbody>
      </table>
    </div>
  </template>
</div>

3 Answers 3

1

This seems like a perfect use case for a computed property:

computed: {
  Code: function () {
    return this.Opcionais
      .filter( opcional => opcional.Qtd > 0 )
      .map( opcional => opcional.Qtd + 'x' + opcional.Code )
      .join( ' | ' );
  }
}

Here's a full working example, showing the code below the table and updating it live:

new Vue({
  el: '#app',
  data() {
    return {
      Opcionais: [
        { Code: 1, Nome: 'Martelo', Valor: 50.00, Qtd: 0 },
        { Code: 2, Nome: 'Serrote', Valor: 50.00, Qtd: 0 },
        { Code: 3, Nome: 'Prego', Valor: 60.00, Qtd: 0 }
      ]
    }
  },
  computed: {
    Code: function () {
      return this.Opcionais
        .filter( opcional => opcional.Qtd > 0 )
        .map( opcional => opcional.Qtd + 'x' + opcional.Code )
        .join( ' | ' );
    }
  }
})
<script src="https://unpkg.com/vue"></script>

<div id="app">
  <template>
    <div class="usuario-lista">
      <table>
        <thead>
          <tr>
            <th>#Code</th>
            <th>Nome</th>
            <th>Valor Unitário</th>
            <th>Valor Total</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="opcional in Opcionais" :key="opcional.Code">
            <td>
              <button @click="opcional.Qtd > 0 && opcional.Qtd--">-</button>
              <input type="text" v-model.number="opcional.Qtd">
              <button @click="opcional.Qtd++">+</button>
            </td>
            <td>{{ opcional.Nome }}</td>
            <td>{{ opcional.Valor }}</td>
            <td>{{ opcional.Valor * opcional.Qtd }}</td>
          </tr>
        </tbody>
      </table>
    </div>
    <p>Code: {{Code}}</p>
  </template>
</div>

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much, that's exactly what I needed, alias was a very simple way to understand
1

Not really familiar with Vue but you can reduce Opcionais like so:

const Opcionais = [
  { Code: 1, Nome: 'Martelo', Valor: 50.00, Qtd: 0 },
  { Code: 2, Nome: 'Serrote', Valor: 50.00, Qtd: 0 },
  { Code: 3, Nome: 'Prego', Valor: 60.00, Qtd: 0 }
];

const result = Opcionais.reduce((arr, { Qtd, Code }) => {
  return [...arr, `${Qtd}x${Code}`];
}, []).join(' | ');

console.log(result);

Comments

-1

You can use the spread operator to preserve the current state and add new items. To join with pipes, use the 'reducer' as answered below or just do it in the html, as you wish.

new Vue({
  el: '#app',
  data() {
    return {
      Opcionais: [
        { Code: 1, Nome: 'Martelo', Valor: 50.00, Qtd: 0 },
        { Code: 2, Nome: 'Serrote', Valor: 50.00, Qtd: 0 },
        { Code: 3, Nome: 'Prego', Valor: 60.00, Qtd: 0 }
      ],
      Elements: []
    }
  },
  methods: {
    addOpcional(opcional) {
      // The variable below should receive the value of the quantity plus the code. If more than one option is chosen the variable must receive this new value and separate with pipe example Qty (2) x Code (2) | Qty (3) x Code (2)
      opcional.Qtd += 1

      this.Elements = [...this.Elements, (opcional.Qtd + 1) + 'x' + opcional.Code]
      },

    remove(opcional) {

    }
  }
})
<script src="https://unpkg.com/vue"></script>

<div id="app">
  <template>
    <div class="usuario-lista">
      <table>
        <thead>
          <tr>
            <th>#Code</th>
            <th>Nome</th>
            <th>Valor Unitário</th>
            <th>Valor Total</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="opcional in Opcionais" :key="opcional.Code">
            <td>
              <button @click="opcional.Qtd ? opcional.Qtd-- : false">-</button>
              <input type="text" :value="opcional.Qtd">
              <button @click="addOpcional(opcional)">+</button>
            </td>
            <td>{{ opcional.Nome }}</td>
            <td>{{ opcional.Valor }}</td>
            <td>{{ opcional.Valor * opcional.Qtd }}</td>
          </tr>
        </tbody>
      </table>
      <pre>{{ Elements.join("|") }}</pre>
    </div>
  </template>
</div>

2 Comments

After running your snippet and clicking the first "+" button a few times, I'm now seeing the string 2x1|3x1|4x1|5x1|6x1|7x1 below the table. I might be wrong, but I'm pretty sure that's not what the OP is looking for. Especially with the quantities being off by one.
Thank you so much, that's exactly what I needed. just needed to check if the value already existed, if yes only increases in quantity does not create another

Your Answer

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